Commit cbec8fba authored by David S. Miller's avatar David S. Miller

Merge davem@nuts.ninka.net:/home/davem/src/BK/net-2.5

into kernel.bkbits.net:/home/davem/net-2.5
parents c2e2d4f7 d171187b
...@@ -31,6 +31,11 @@ ipfrag_low_thresh - INTEGER ...@@ -31,6 +31,11 @@ ipfrag_low_thresh - INTEGER
ipfrag_time - INTEGER ipfrag_time - INTEGER
Time in seconds to keep an IP fragment in memory. Time in seconds to keep an IP fragment in memory.
ipfrag_secret_interval - INTEGER
Regeneration interval (in seconds) of the hash secret (or lifetime
for the hash secret) for IP fragments.
Default: 600
INET peer storage: INET peer storage:
inet_peer_threshold - INTEGER inet_peer_threshold - INTEGER
...@@ -515,6 +520,25 @@ bindv6only - BOOLEAN ...@@ -515,6 +520,25 @@ bindv6only - BOOLEAN
Default: FALSE (as specified in RFC2553bis) Default: FALSE (as specified in RFC2553bis)
IPv6 Fragmentation:
ip6frag_high_thresh - INTEGER
Maximum memory used to reassemble IPv6 fragments. When
ip6frag_high_thresh bytes of memory is allocated for this purpose,
the fragment handler will toss packets until ip6frag_low_thresh
is reached.
ip6frag_low_thresh - INTEGER
See ip6frag_high_thresh
ip6frag_time - INTEGER
Time in seconds to keep an IPv6 fragment in memory.
ip6frag_secret_interval - INTEGER
Regeneration interval (in seconds) of the hash secret (or lifetime
for the hash secret) for IPv6 fragments.
Default: 600
conf/default/*: conf/default/*:
Change the interface-specific default settings. Change the interface-specific default settings.
......
...@@ -304,7 +304,7 @@ static int eth_configure(int n, void *init, char *mac, ...@@ -304,7 +304,7 @@ static int eth_configure(int n, void *init, char *mac,
} }
memset(device, 0, sizeof(*device)); memset(device, 0, sizeof(*device));
device->list = INIT_LIST_HEAD(device->list); INIT_LIST_HEAD(&device->list);
device->index = n; device->index = n;
spin_lock(&devices_lock); spin_lock(&devices_lock);
...@@ -362,7 +362,7 @@ static int eth_configure(int n, void *init, char *mac, ...@@ -362,7 +362,7 @@ static int eth_configure(int n, void *init, char *mac,
return 1; return 1;
lp = dev->priv; lp = dev->priv;
lp->list = INIT_LIST_HEAD(lp->list); INIT_LIST_HEAD(&lp->list);
spin_lock_init(&lp->lock); spin_lock_init(&lp->lock);
lp->dev = dev; lp->dev = dev;
lp->fd = -1; lp->fd = -1;
...@@ -537,7 +537,7 @@ static int eth_setup(char *str) ...@@ -537,7 +537,7 @@ static int eth_setup(char *str)
return(1); return(1);
} }
new->list = INIT_LIST_HEAD(new->list); INIT_LIST_HEAD(&new->list);
new->index = n; new->index = n;
new->init = str; new->init = str;
......
...@@ -6,16 +6,12 @@ menu "Cryptographic options" ...@@ -6,16 +6,12 @@ menu "Cryptographic options"
config CRYPTO config CRYPTO
bool "Cryptographic API" bool "Cryptographic API"
default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m || INET6_AH=y || INET6_AH=m || \
INET6_ESP=y || INET6_ESP=m || INET6_IPCOMP=y || INET6_IPCOMP=m || IPV6_PRIVACY=y
help help
This option provides the core Cryptographic API. This option provides the core Cryptographic API.
config CRYPTO_HMAC config CRYPTO_HMAC
bool "HMAC support" bool "HMAC support"
depends on CRYPTO depends on CRYPTO
default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m || INET6_AH=y || INET6_AH=m || \
INET6_ESP=y || INET6_ESP=m
help help
HMAC: Keyed-Hashing for Message Authentication (RFC2104). HMAC: Keyed-Hashing for Message Authentication (RFC2104).
This is required for IPSec. This is required for IPSec.
...@@ -35,16 +31,12 @@ config CRYPTO_MD4 ...@@ -35,16 +31,12 @@ config CRYPTO_MD4
config CRYPTO_MD5 config CRYPTO_MD5
tristate "MD5 digest algorithm" tristate "MD5 digest algorithm"
depends on CRYPTO depends on CRYPTO
default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m || INET6_AH=y || INET6_AH=m || \
INET6_ESP=y || INET6_ESP=m || IPV6_PRIVACY=y
help help
MD5 message digest algorithm (RFC1321). MD5 message digest algorithm (RFC1321).
config CRYPTO_SHA1 config CRYPTO_SHA1
tristate "SHA1 digest algorithm" tristate "SHA1 digest algorithm"
depends on CRYPTO depends on CRYPTO
default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m || INET6_AH=y || INET6_AH=m || \
INET6_ESP=y || INET6_ESP=m
help help
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
...@@ -72,7 +64,6 @@ config CRYPTO_SHA512 ...@@ -72,7 +64,6 @@ config CRYPTO_SHA512
config CRYPTO_DES config CRYPTO_DES
tristate "DES and Triple DES EDE cipher algorithms" tristate "DES and Triple DES EDE cipher algorithms"
depends on CRYPTO depends on CRYPTO
default y if INET_ESP=y || INET_ESP=m || INET6_ESP=y || INET6_ESP=m
help help
DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
...@@ -138,7 +129,6 @@ config CRYPTO_AES ...@@ -138,7 +129,6 @@ config CRYPTO_AES
config CRYPTO_DEFLATE config CRYPTO_DEFLATE
tristate "Deflate compression algorithm" tristate "Deflate compression algorithm"
depends on CRYPTO depends on CRYPTO
default y if INET_IPCOMP=y || INET_IPCOMP=m || INET6_IPCOMP=y || INET6_IPCOMP=m
help help
This is the Deflate algorithm (RFC1951), specified for use in This is the Deflate algorithm (RFC1951), specified for use in
IPSec with the IPCOMP protocol (RFC3173, RFC2394). IPSec with the IPCOMP protocol (RFC3173, RFC2394).
......
...@@ -77,14 +77,6 @@ ...@@ -77,14 +77,6 @@
#include <linux/atmdev.h> #include <linux/atmdev.h>
#include <linux/atm.h> #include <linux/atm.h>
#include <linux/sonet.h> #include <linux/sonet.h>
#ifndef ATM_OC12_PCR
#define ATM_OC12_PCR (622080000/1080*1040/8/53)
#endif
#ifdef BUS_INT_WAR
void sn_add_polled_interrupt(int irq, int interval);
void sn_delete_polled_interrupt(int irq);
#endif
#define USE_TASKLET #define USE_TASKLET
#define USE_HE_FIND_VCC #define USE_HE_FIND_VCC
...@@ -171,22 +163,17 @@ static short sdh = 1; ...@@ -171,22 +163,17 @@ static short sdh = 1;
static struct atmdev_ops he_ops = static struct atmdev_ops he_ops =
{ {
open: he_open, .open = he_open,
close: he_close, .close = he_close,
ioctl: he_ioctl, .ioctl = he_ioctl,
send: he_send, .send = he_send,
sg_send: he_sg_send, .sg_send = he_sg_send,
phy_put: he_phy_put, .phy_put = he_phy_put,
phy_get: he_phy_get, .phy_get = he_phy_get,
proc_read: he_proc_read, .proc_read = he_proc_read,
owner: THIS_MODULE .owner = THIS_MODULE
}; };
/* see the comments in he.h about global_lock */
#define HE_SPIN_LOCK(dev, flags) spin_lock_irqsave(&(dev)->global_lock, flags)
#define HE_SPIN_UNLOCK(dev, flags) spin_unlock_irqrestore(&(dev)->global_lock, flags)
#define he_writel(dev, val, reg) do { writel(val, (dev)->membase + (reg)); wmb(); } while (0) #define he_writel(dev, val, reg) do { writel(val, (dev)->membase + (reg)); wmb(); } while (0)
#define he_readl(dev, reg) readl((dev)->membase + (reg)) #define he_readl(dev, reg) readl((dev)->membase + (reg))
...@@ -233,26 +220,26 @@ he_readl_internal(struct he_dev *he_dev, unsigned addr, unsigned flags) ...@@ -233,26 +220,26 @@ he_readl_internal(struct he_dev *he_dev, unsigned addr, unsigned flags)
/* figure 2.2 connection id */ /* figure 2.2 connection id */
#define he_mkcid(dev, vpi, vci) (((vpi<<(dev)->vcibits) | vci) & 0x1fff) #define he_mkcid(dev, vpi, vci) (((vpi << (dev)->vcibits) | vci) & 0x1fff)
/* 2.5.1 per connection transmit state registers */ /* 2.5.1 per connection transmit state registers */
#define he_writel_tsr0(dev, val, cid) \ #define he_writel_tsr0(dev, val, cid) \
he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 0) he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 0)
#define he_readl_tsr0(dev, cid) \ #define he_readl_tsr0(dev, cid) \
he_readl_tcm(dev, CONFIG_TSRA | (cid<<3) | 0) he_readl_tcm(dev, CONFIG_TSRA | (cid << 3) | 0)
#define he_writel_tsr1(dev, val, cid) \ #define he_writel_tsr1(dev, val, cid) \
he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 1) he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 1)
#define he_writel_tsr2(dev, val, cid) \ #define he_writel_tsr2(dev, val, cid) \
he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 2) he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 2)
#define he_writel_tsr3(dev, val, cid) \ #define he_writel_tsr3(dev, val, cid) \
he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 3) he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 3)
#define he_writel_tsr4(dev, val, cid) \ #define he_writel_tsr4(dev, val, cid) \
he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 4) he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 4)
/* from page 2-20 /* from page 2-20
* *
...@@ -263,43 +250,43 @@ he_readl_internal(struct he_dev *he_dev, unsigned addr, unsigned flags) ...@@ -263,43 +250,43 @@ he_readl_internal(struct he_dev *he_dev, unsigned addr, unsigned flags)
*/ */
#define he_writel_tsr4_upper(dev, val, cid) \ #define he_writel_tsr4_upper(dev, val, cid) \
he_writel_internal(dev, val, CONFIG_TSRA | (cid<<3) | 4, \ he_writel_internal(dev, val, CONFIG_TSRA | (cid << 3) | 4, \
CON_CTL_TCM \ CON_CTL_TCM \
| CON_BYTE_DISABLE_2 \ | CON_BYTE_DISABLE_2 \
| CON_BYTE_DISABLE_1 \ | CON_BYTE_DISABLE_1 \
| CON_BYTE_DISABLE_0) | CON_BYTE_DISABLE_0)
#define he_readl_tsr4(dev, cid) \ #define he_readl_tsr4(dev, cid) \
he_readl_tcm(dev, CONFIG_TSRA | (cid<<3) | 4) he_readl_tcm(dev, CONFIG_TSRA | (cid << 3) | 4)
#define he_writel_tsr5(dev, val, cid) \ #define he_writel_tsr5(dev, val, cid) \
he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 5) he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 5)
#define he_writel_tsr6(dev, val, cid) \ #define he_writel_tsr6(dev, val, cid) \
he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 6) he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 6)
#define he_writel_tsr7(dev, val, cid) \ #define he_writel_tsr7(dev, val, cid) \
he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 7) he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 7)
#define he_writel_tsr8(dev, val, cid) \ #define he_writel_tsr8(dev, val, cid) \
he_writel_tcm(dev, val, CONFIG_TSRB | (cid<<2) | 0) he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 0)
#define he_writel_tsr9(dev, val, cid) \ #define he_writel_tsr9(dev, val, cid) \
he_writel_tcm(dev, val, CONFIG_TSRB | (cid<<2) | 1) he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 1)
#define he_writel_tsr10(dev, val, cid) \ #define he_writel_tsr10(dev, val, cid) \
he_writel_tcm(dev, val, CONFIG_TSRB | (cid<<2) | 2) he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 2)
#define he_writel_tsr11(dev, val, cid) \ #define he_writel_tsr11(dev, val, cid) \
he_writel_tcm(dev, val, CONFIG_TSRB | (cid<<2) | 3) he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 3)
#define he_writel_tsr12(dev, val, cid) \ #define he_writel_tsr12(dev, val, cid) \
he_writel_tcm(dev, val, CONFIG_TSRC | (cid<<1) | 0) he_writel_tcm(dev, val, CONFIG_TSRC | (cid << 1) | 0)
#define he_writel_tsr13(dev, val, cid) \ #define he_writel_tsr13(dev, val, cid) \
he_writel_tcm(dev, val, CONFIG_TSRC | (cid<<1) | 1) he_writel_tcm(dev, val, CONFIG_TSRC | (cid << 1) | 1)
#define he_writel_tsr14(dev, val, cid) \ #define he_writel_tsr14(dev, val, cid) \
...@@ -315,30 +302,30 @@ he_readl_internal(struct he_dev *he_dev, unsigned addr, unsigned flags) ...@@ -315,30 +302,30 @@ he_readl_internal(struct he_dev *he_dev, unsigned addr, unsigned flags)
/* 2.7.1 per connection receive state registers */ /* 2.7.1 per connection receive state registers */
#define he_writel_rsr0(dev, val, cid) \ #define he_writel_rsr0(dev, val, cid) \
he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 0) he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 0)
#define he_readl_rsr0(dev, cid) \ #define he_readl_rsr0(dev, cid) \
he_readl_rcm(dev, 0x00000 | (cid<<3) | 0) he_readl_rcm(dev, 0x00000 | (cid << 3) | 0)
#define he_writel_rsr1(dev, val, cid) \ #define he_writel_rsr1(dev, val, cid) \
he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 1) he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 1)
#define he_writel_rsr2(dev, val, cid) \ #define he_writel_rsr2(dev, val, cid) \
he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 2) he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 2)
#define he_writel_rsr3(dev, val, cid) \ #define he_writel_rsr3(dev, val, cid) \
he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 3) he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 3)
#define he_writel_rsr4(dev, val, cid) \ #define he_writel_rsr4(dev, val, cid) \
he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 4) he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 4)
#define he_writel_rsr5(dev, val, cid) \ #define he_writel_rsr5(dev, val, cid) \
he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 5) he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 5)
#define he_writel_rsr6(dev, val, cid) \ #define he_writel_rsr6(dev, val, cid) \
he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 6) he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 6)
#define he_writel_rsr7(dev, val, cid) \ #define he_writel_rsr7(dev, val, cid) \
he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 7) he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 7)
static __inline__ struct atm_vcc* static __inline__ struct atm_vcc*
he_find_vcc(struct he_dev *he_dev, unsigned cid) he_find_vcc(struct he_dev *he_dev, unsigned cid)
...@@ -349,7 +336,7 @@ he_find_vcc(struct he_dev *he_dev, unsigned cid) ...@@ -349,7 +336,7 @@ he_find_vcc(struct he_dev *he_dev, unsigned cid)
int vci; int vci;
vpi = cid >> he_dev->vcibits; vpi = cid >> he_dev->vcibits;
vci = cid & ((1<<he_dev->vcibits)-1); vci = cid & ((1 << he_dev->vcibits) - 1);
spin_lock_irqsave(&he_dev->atm_dev->lock, flags); spin_lock_irqsave(&he_dev->atm_dev->lock, flags);
for (vcc = he_dev->atm_dev->vccs; vcc; vcc = vcc->next) for (vcc = he_dev->atm_dev->vccs; vcc; vcc = vcc->next)
...@@ -443,12 +430,12 @@ he_remove_one (struct pci_dev *pci_dev) ...@@ -443,12 +430,12 @@ he_remove_one (struct pci_dev *pci_dev)
static unsigned static unsigned
rate_to_atmf(unsigned rate) /* cps to atm forum format */ rate_to_atmf(unsigned rate) /* cps to atm forum format */
{ {
#define NONZERO (1<<14) #define NONZERO (1 << 14)
unsigned exp = 0; unsigned exp = 0;
if (rate == 0) if (rate == 0)
return(0); return 0;
rate <<= 9; rate <<= 9;
while (rate > 0x3ff) { while (rate > 0x3ff) {
...@@ -761,26 +748,27 @@ he_init_cs_block_rcm(struct he_dev *he_dev) ...@@ -761,26 +748,27 @@ he_init_cs_block_rcm(struct he_dev *he_dev)
(he_dev->atm_dev->link_rate * 2); (he_dev->atm_dev->link_rate * 2);
#else #else
/* this is pretty, but avoids _divdu3 and is mostly correct */ /* this is pretty, but avoids _divdu3 and is mostly correct */
buf = 0;
mult = he_dev->atm_dev->link_rate / ATM_OC3_PCR; mult = he_dev->atm_dev->link_rate / ATM_OC3_PCR;
if (rate_cps > (68 * mult))
buf = 1;
if (rate_cps > (136 * mult))
buf = 2;
if (rate_cps > (204 * mult))
buf = 3;
if (rate_cps > (272 * mult)) if (rate_cps > (272 * mult))
buf = 4; buf = 4;
else if (rate_cps > (204 * mult))
buf = 3;
else if (rate_cps > (136 * mult))
buf = 2;
else if (rate_cps > (68 * mult))
buf = 1;
else
buf = 0;
#endif #endif
if (buf > buf_limit) if (buf > buf_limit)
buf = buf_limit; buf = buf_limit;
reg = (reg<<16) | ((i<<8) | buf); reg = (reg << 16) | ((i << 8) | buf);
#define RTGTBL_OFFSET 0x400 #define RTGTBL_OFFSET 0x400
if (rate_atmf & 0x1) if (rate_atmf & 0x1)
he_writel_rcm(he_dev, reg, he_writel_rcm(he_dev, reg,
CONFIG_RCMABR + RTGTBL_OFFSET + (rate_atmf>>1)); CONFIG_RCMABR + RTGTBL_OFFSET + (rate_atmf >> 1));
++rate_atmf; ++rate_atmf;
} }
...@@ -839,7 +827,7 @@ he_init_group(struct he_dev *he_dev, int group) ...@@ -839,7 +827,7 @@ he_init_group(struct he_dev *he_dev, int group)
he_dev->rbps_base[i].phys = dma_handle; he_dev->rbps_base[i].phys = dma_handle;
} }
he_dev->rbps_tail = &he_dev->rbps_base[CONFIG_RBPS_SIZE-1]; he_dev->rbps_tail = &he_dev->rbps_base[CONFIG_RBPS_SIZE - 1];
he_writel(he_dev, he_dev->rbps_phys, G0_RBPS_S + (group * 32)); he_writel(he_dev, he_dev->rbps_phys, G0_RBPS_S + (group * 32));
he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail), he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail),
...@@ -848,7 +836,7 @@ he_init_group(struct he_dev *he_dev, int group) ...@@ -848,7 +836,7 @@ he_init_group(struct he_dev *he_dev, int group)
G0_RBPS_BS + (group * 32)); G0_RBPS_BS + (group * 32));
he_writel(he_dev, he_writel(he_dev,
RBP_THRESH(CONFIG_RBPS_THRESH) | RBP_THRESH(CONFIG_RBPS_THRESH) |
RBP_QSIZE(CONFIG_RBPS_SIZE-1) | RBP_QSIZE(CONFIG_RBPS_SIZE - 1) |
RBP_INT_ENB, RBP_INT_ENB,
G0_RBPS_QI + (group * 32)); G0_RBPS_QI + (group * 32));
#else /* !USE_RBPS */ #else /* !USE_RBPS */
...@@ -902,7 +890,7 @@ he_init_group(struct he_dev *he_dev, int group) ...@@ -902,7 +890,7 @@ he_init_group(struct he_dev *he_dev, int group)
he_dev->rbpl_base[i].status = RBP_LOANED | (i << RBP_INDEX_OFF); he_dev->rbpl_base[i].status = RBP_LOANED | (i << RBP_INDEX_OFF);
he_dev->rbpl_base[i].phys = dma_handle; he_dev->rbpl_base[i].phys = dma_handle;
} }
he_dev->rbpl_tail = &he_dev->rbpl_base[CONFIG_RBPL_SIZE-1]; he_dev->rbpl_tail = &he_dev->rbpl_base[CONFIG_RBPL_SIZE - 1];
he_writel(he_dev, he_dev->rbpl_phys, G0_RBPL_S + (group * 32)); he_writel(he_dev, he_dev->rbpl_phys, G0_RBPL_S + (group * 32));
he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail), he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail),
...@@ -911,7 +899,7 @@ he_init_group(struct he_dev *he_dev, int group) ...@@ -911,7 +899,7 @@ he_init_group(struct he_dev *he_dev, int group)
G0_RBPL_BS + (group * 32)); G0_RBPL_BS + (group * 32));
he_writel(he_dev, he_writel(he_dev,
RBP_THRESH(CONFIG_RBPL_THRESH) | RBP_THRESH(CONFIG_RBPL_THRESH) |
RBP_QSIZE(CONFIG_RBPL_SIZE-1) | RBP_QSIZE(CONFIG_RBPL_SIZE - 1) |
RBP_INT_ENB, RBP_INT_ENB,
G0_RBPL_QI + (group * 32)); G0_RBPL_QI + (group * 32));
...@@ -929,7 +917,7 @@ he_init_group(struct he_dev *he_dev, int group) ...@@ -929,7 +917,7 @@ he_init_group(struct he_dev *he_dev, int group)
he_writel(he_dev, he_dev->rbrq_phys, G0_RBRQ_ST + (group * 16)); he_writel(he_dev, he_dev->rbrq_phys, G0_RBRQ_ST + (group * 16));
he_writel(he_dev, 0, G0_RBRQ_H + (group * 16)); he_writel(he_dev, 0, G0_RBRQ_H + (group * 16));
he_writel(he_dev, he_writel(he_dev,
RBRQ_THRESH(CONFIG_RBRQ_THRESH) | RBRQ_SIZE(CONFIG_RBRQ_SIZE-1), RBRQ_THRESH(CONFIG_RBRQ_THRESH) | RBRQ_SIZE(CONFIG_RBRQ_SIZE - 1),
G0_RBRQ_Q + (group * 16)); G0_RBRQ_Q + (group * 16));
if (irq_coalesce) { if (irq_coalesce) {
hprintk("coalescing interrupts\n"); hprintk("coalescing interrupts\n");
...@@ -979,7 +967,7 @@ he_init_irq(struct he_dev *he_dev) ...@@ -979,7 +967,7 @@ he_init_irq(struct he_dev *he_dev)
he_dev->irq_head = he_dev->irq_base; he_dev->irq_head = he_dev->irq_base;
he_dev->irq_tail = he_dev->irq_base; he_dev->irq_tail = he_dev->irq_base;
for (i=0; i < CONFIG_IRQ_SIZE; ++i) for (i = 0; i < CONFIG_IRQ_SIZE; ++i)
he_dev->irq_base[i].isw = ITYPE_INVALID; he_dev->irq_base[i].isw = ITYPE_INVALID;
he_writel(he_dev, he_dev->irq_phys, IRQ0_BASE); he_writel(he_dev, he_dev->irq_phys, IRQ0_BASE);
...@@ -1018,11 +1006,6 @@ he_init_irq(struct he_dev *he_dev) ...@@ -1018,11 +1006,6 @@ he_init_irq(struct he_dev *he_dev)
he_dev->irq = he_dev->pci_dev->irq; he_dev->irq = he_dev->pci_dev->irq;
#ifdef BUS_INT_WAR
HPRINTK("sn_add_polled_interrupt(irq %d, 1)\n", he_dev->irq);
sn_add_polled_interrupt(he_dev->irq, 1);
#endif
return 0; return 0;
} }
...@@ -1138,12 +1121,12 @@ he_start(struct atm_dev *dev) ...@@ -1138,12 +1121,12 @@ he_start(struct atm_dev *dev)
pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0); pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0);
/* 4.7 read prom contents */ /* 4.7 read prom contents */
for (i=0; i<PROD_ID_LEN; ++i) for (i = 0; i < PROD_ID_LEN; ++i)
he_dev->prod_id[i] = read_prom_byte(he_dev, PROD_ID + i); he_dev->prod_id[i] = read_prom_byte(he_dev, PROD_ID + i);
he_dev->media = read_prom_byte(he_dev, MEDIA); he_dev->media = read_prom_byte(he_dev, MEDIA);
for (i=0; i<6; ++i) for (i = 0; i < 6; ++i)
dev->esi[i] = read_prom_byte(he_dev, MAC_ADDR + i); dev->esi[i] = read_prom_byte(he_dev, MAC_ADDR + i);
hprintk("%s%s, %x:%x:%x:%x:%x:%x\n", hprintk("%s%s, %x:%x:%x:%x:%x:%x\n",
...@@ -1323,15 +1306,15 @@ he_start(struct atm_dev *dev) ...@@ -1323,15 +1306,15 @@ he_start(struct atm_dev *dev)
he_writel(he_dev, 0x0, TXAAL5_PROTO); he_writel(he_dev, 0x0, TXAAL5_PROTO);
he_writel(he_dev, PHY_INT_ENB | he_writel(he_dev, PHY_INT_ENB |
(he_is622(he_dev) ? PTMR_PRE(67-1) : PTMR_PRE(50-1)), (he_is622(he_dev) ? PTMR_PRE(67 - 1) : PTMR_PRE(50 - 1)),
RH_CONFIG); RH_CONFIG);
/* 5.1.3 initialize connection memory */ /* 5.1.3 initialize connection memory */
for (i=0; i < TCM_MEM_SIZE; ++i) for (i = 0; i < TCM_MEM_SIZE; ++i)
he_writel_tcm(he_dev, 0, i); he_writel_tcm(he_dev, 0, i);
for (i=0; i < RCM_MEM_SIZE; ++i) for (i = 0; i < RCM_MEM_SIZE; ++i)
he_writel_rcm(he_dev, 0, i); he_writel_rcm(he_dev, 0, i);
/* /*
...@@ -1512,7 +1495,7 @@ he_start(struct atm_dev *dev) ...@@ -1512,7 +1495,7 @@ he_start(struct atm_dev *dev)
} }
he_dev->tpd_head = he_dev->tpd_base; he_dev->tpd_head = he_dev->tpd_base;
he_dev->tpd_end = &he_dev->tpd_base[CONFIG_NUMTPDS-1]; he_dev->tpd_end = &he_dev->tpd_base[CONFIG_NUMTPDS - 1];
#endif #endif
if (he_init_group(he_dev, 0) != 0) if (he_init_group(he_dev, 0) != 0)
...@@ -1652,12 +1635,8 @@ he_stop(struct he_dev *he_dev) ...@@ -1652,12 +1635,8 @@ he_stop(struct he_dev *he_dev)
he_dev->atm_dev->phy->stop(he_dev->atm_dev); he_dev->atm_dev->phy->stop(he_dev->atm_dev);
#endif /* CONFIG_ATM_HE_USE_SUNI */ #endif /* CONFIG_ATM_HE_USE_SUNI */
if (he_dev->irq) { if (he_dev->irq)
#ifdef BUS_INT_WAR
sn_delete_polled_interrupt(he_dev->irq);
#endif
free_irq(he_dev->irq, he_dev); free_irq(he_dev->irq, he_dev);
}
if (he_dev->irq_base) if (he_dev->irq_base)
pci_free_consistent(he_dev->pci_dev, (CONFIG_IRQ_SIZE+1) pci_free_consistent(he_dev->pci_dev, (CONFIG_IRQ_SIZE+1)
...@@ -1669,7 +1648,7 @@ he_stop(struct he_dev *he_dev) ...@@ -1669,7 +1648,7 @@ he_stop(struct he_dev *he_dev)
if (he_dev->rbpl_base) { if (he_dev->rbpl_base) {
#ifdef USE_RBPL_POOL #ifdef USE_RBPL_POOL
for (i=0; i<CONFIG_RBPL_SIZE; ++i) { for (i = 0; i < CONFIG_RBPL_SIZE; ++i) {
void *cpuaddr = he_dev->rbpl_virt[i].virt; void *cpuaddr = he_dev->rbpl_virt[i].virt;
dma_addr_t dma_handle = he_dev->rbpl_base[i].phys; dma_addr_t dma_handle = he_dev->rbpl_base[i].phys;
...@@ -1691,7 +1670,7 @@ he_stop(struct he_dev *he_dev) ...@@ -1691,7 +1670,7 @@ he_stop(struct he_dev *he_dev)
#ifdef USE_RBPS #ifdef USE_RBPS
if (he_dev->rbps_base) { if (he_dev->rbps_base) {
#ifdef USE_RBPS_POOL #ifdef USE_RBPS_POOL
for (i=0; i<CONFIG_RBPS_SIZE; ++i) { for (i = 0; i < CONFIG_RBPS_SIZE; ++i) {
void *cpuaddr = he_dev->rbps_virt[i].virt; void *cpuaddr = he_dev->rbps_virt[i].virt;
dma_addr_t dma_handle = he_dev->rbps_base[i].phys; dma_addr_t dma_handle = he_dev->rbps_base[i].phys;
...@@ -1790,7 +1769,7 @@ __alloc_tpd(struct he_dev *he_dev) ...@@ -1790,7 +1769,7 @@ __alloc_tpd(struct he_dev *he_dev)
} }
#define AAL5_LEN(buf,len) \ #define AAL5_LEN(buf,len) \
((((unsigned char *)(buf))[(len)-6]<<8) | \ ((((unsigned char *)(buf))[(len)-6] << 8) | \
(((unsigned char *)(buf))[(len)-5])) (((unsigned char *)(buf))[(len)-5]))
/* 2.10.1.2 receive /* 2.10.1.2 receive
...@@ -1800,7 +1779,7 @@ __alloc_tpd(struct he_dev *he_dev) ...@@ -1800,7 +1779,7 @@ __alloc_tpd(struct he_dev *he_dev)
*/ */
#define TCP_CKSUM(buf,len) \ #define TCP_CKSUM(buf,len) \
((((unsigned char *)(buf))[(len)-2]<<8) | \ ((((unsigned char *)(buf))[(len)-2] << 8) | \
(((unsigned char *)(buf))[(len-1)])) (((unsigned char *)(buf))[(len-1)]))
static int static int
...@@ -2171,7 +2150,7 @@ he_tasklet(unsigned long data) ...@@ -2171,7 +2150,7 @@ he_tasklet(unsigned long data)
HPRINTK("tasklet (0x%lx)\n", data); HPRINTK("tasklet (0x%lx)\n", data);
#ifdef USE_TASKLET #ifdef USE_TASKLET
HE_SPIN_LOCK(he_dev, flags); spin_lock_irqsave(&he_dev->global_lock, flags);
#endif #endif
while (he_dev->irq_head != he_dev->irq_tail) { while (he_dev->irq_head != he_dev->irq_tail) {
...@@ -2209,10 +2188,10 @@ he_tasklet(unsigned long data) ...@@ -2209,10 +2188,10 @@ he_tasklet(unsigned long data)
case ITYPE_PHY: case ITYPE_PHY:
HPRINTK("phy interrupt\n"); HPRINTK("phy interrupt\n");
#ifdef CONFIG_ATM_HE_USE_SUNI #ifdef CONFIG_ATM_HE_USE_SUNI
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
if (he_dev->atm_dev->phy && he_dev->atm_dev->phy->interrupt) if (he_dev->atm_dev->phy && he_dev->atm_dev->phy->interrupt)
he_dev->atm_dev->phy->interrupt(he_dev->atm_dev); he_dev->atm_dev->phy->interrupt(he_dev->atm_dev);
HE_SPIN_LOCK(he_dev, flags); spin_lock_irqsave(&he_dev->global_lock, flags);
#endif #endif
break; break;
case ITYPE_OTHER: case ITYPE_OTHER:
...@@ -2257,7 +2236,7 @@ he_tasklet(unsigned long data) ...@@ -2257,7 +2236,7 @@ he_tasklet(unsigned long data)
(void) he_readl(he_dev, INT_FIFO); /* 8.1.2 controller errata */ (void) he_readl(he_dev, INT_FIFO); /* 8.1.2 controller errata */
} }
#ifdef USE_TASKLET #ifdef USE_TASKLET
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
#endif #endif
} }
...@@ -2271,7 +2250,7 @@ he_irq_handler(int irq, void *dev_id, struct pt_regs *regs) ...@@ -2271,7 +2250,7 @@ he_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
if (he_dev == NULL) if (he_dev == NULL)
return IRQ_NONE; return IRQ_NONE;
HE_SPIN_LOCK(he_dev, flags); spin_lock_irqsave(&he_dev->global_lock, flags);
he_dev->irq_tail = (struct he_irq *) (((unsigned long)he_dev->irq_base) | he_dev->irq_tail = (struct he_irq *) (((unsigned long)he_dev->irq_base) |
(*he_dev->irq_tailoffset << 2)); (*he_dev->irq_tailoffset << 2));
...@@ -2301,7 +2280,7 @@ he_irq_handler(int irq, void *dev_id, struct pt_regs *regs) ...@@ -2301,7 +2280,7 @@ he_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
(void) he_readl(he_dev, INT_FIFO); (void) he_readl(he_dev, INT_FIFO);
#endif #endif
} }
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
return IRQ_RETVAL(handled); return IRQ_RETVAL(handled);
} }
...@@ -2438,9 +2417,9 @@ he_open(struct atm_vcc *vcc, short vpi, int vci) ...@@ -2438,9 +2417,9 @@ he_open(struct atm_vcc *vcc, short vpi, int vci)
goto open_failed; goto open_failed;
} }
HE_SPIN_LOCK(he_dev, flags); spin_lock_irqsave(&he_dev->global_lock, flags);
tsr0 = he_readl_tsr0(he_dev, cid); tsr0 = he_readl_tsr0(he_dev, cid);
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
if (TSR0_CONN_STATE(tsr0) != 0) { if (TSR0_CONN_STATE(tsr0) != 0) {
hprintk("cid 0x%x not idle (tsr0 = 0x%x)\n", cid, tsr0); hprintk("cid 0x%x not idle (tsr0 = 0x%x)\n", cid, tsr0);
...@@ -2467,7 +2446,7 @@ he_open(struct atm_vcc *vcc, short vpi, int vci) ...@@ -2467,7 +2446,7 @@ he_open(struct atm_vcc *vcc, short vpi, int vci)
goto open_failed; goto open_failed;
} }
HE_SPIN_LOCK(he_dev, flags); /* also protects he_dev->cs_stper[] */ spin_lock_irqsave(&he_dev->global_lock, flags); /* also protects he_dev->cs_stper[] */
/* find an unused cs_stper register */ /* find an unused cs_stper register */
for (reg = 0; reg < HE_NUM_CS_STPER; ++reg) for (reg = 0; reg < HE_NUM_CS_STPER; ++reg)
...@@ -2477,7 +2456,7 @@ he_open(struct atm_vcc *vcc, short vpi, int vci) ...@@ -2477,7 +2456,7 @@ he_open(struct atm_vcc *vcc, short vpi, int vci)
if (reg == HE_NUM_CS_STPER) { if (reg == HE_NUM_CS_STPER) {
err = -EBUSY; err = -EBUSY;
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
goto open_failed; goto open_failed;
} }
...@@ -2495,7 +2474,7 @@ he_open(struct atm_vcc *vcc, short vpi, int vci) ...@@ -2495,7 +2474,7 @@ he_open(struct atm_vcc *vcc, short vpi, int vci)
he_writel_mbox(he_dev, rate_to_atmf(period/2), he_writel_mbox(he_dev, rate_to_atmf(period/2),
CS_STPER0 + reg); CS_STPER0 + reg);
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
tsr0 = TSR0_CBR | TSR0_GROUP(0) | tsr0_aal | tsr0 = TSR0_CBR | TSR0_GROUP(0) | tsr0_aal |
TSR0_RC_INDEX(reg); TSR0_RC_INDEX(reg);
...@@ -2506,7 +2485,7 @@ he_open(struct atm_vcc *vcc, short vpi, int vci) ...@@ -2506,7 +2485,7 @@ he_open(struct atm_vcc *vcc, short vpi, int vci)
goto open_failed; goto open_failed;
} }
HE_SPIN_LOCK(he_dev, flags); spin_lock_irqsave(&he_dev->global_lock, flags);
he_writel_tsr0(he_dev, tsr0, cid); he_writel_tsr0(he_dev, tsr0, cid);
he_writel_tsr4(he_dev, tsr4 | 1, cid); he_writel_tsr4(he_dev, tsr4 | 1, cid);
...@@ -2528,7 +2507,7 @@ he_open(struct atm_vcc *vcc, short vpi, int vci) ...@@ -2528,7 +2507,7 @@ he_open(struct atm_vcc *vcc, short vpi, int vci)
#ifdef CONFIG_IA64_SGI_SN2 #ifdef CONFIG_IA64_SGI_SN2
(void) he_readl_tsr0(he_dev, cid); (void) he_readl_tsr0(he_dev, cid);
#endif #endif
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
} }
if (vcc->qos.rxtp.traffic_class != ATM_NONE) { if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
...@@ -2549,11 +2528,11 @@ he_open(struct atm_vcc *vcc, short vpi, int vci) ...@@ -2549,11 +2528,11 @@ he_open(struct atm_vcc *vcc, short vpi, int vci)
goto open_failed; goto open_failed;
} }
HE_SPIN_LOCK(he_dev, flags); spin_lock_irqsave(&he_dev->global_lock, flags);
rsr0 = he_readl_rsr0(he_dev, cid); rsr0 = he_readl_rsr0(he_dev, cid);
if (rsr0 & RSR0_OPEN_CONN) { if (rsr0 & RSR0_OPEN_CONN) {
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
hprintk("cid 0x%x not idle (rsr0 = 0x%x)\n", cid, rsr0); hprintk("cid 0x%x not idle (rsr0 = 0x%x)\n", cid, rsr0);
err = -EBUSY; err = -EBUSY;
...@@ -2585,7 +2564,7 @@ he_open(struct atm_vcc *vcc, short vpi, int vci) ...@@ -2585,7 +2564,7 @@ he_open(struct atm_vcc *vcc, short vpi, int vci)
(void) he_readl_rsr0(he_dev, cid); (void) he_readl_rsr0(he_dev, cid);
#endif #endif
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
#ifndef USE_HE_FIND_VCC #ifndef USE_HE_FIND_VCC
HE_LOOKUP_VCC(he_dev, cid) = vcc; HE_LOOKUP_VCC(he_dev, cid) = vcc;
...@@ -2631,7 +2610,7 @@ he_close(struct atm_vcc *vcc) ...@@ -2631,7 +2610,7 @@ he_close(struct atm_vcc *vcc)
/* wait for previous close (if any) to finish */ /* wait for previous close (if any) to finish */
HE_SPIN_LOCK(he_dev, flags); spin_lock_irqsave(&he_dev->global_lock, flags);
while (he_readl(he_dev, RCC_STAT) & RCC_BUSY) { while (he_readl(he_dev, RCC_STAT) & RCC_BUSY) {
HPRINTK("close cid 0x%x RCC_BUSY\n", cid); HPRINTK("close cid 0x%x RCC_BUSY\n", cid);
udelay(250); udelay(250);
...@@ -2645,7 +2624,7 @@ he_close(struct atm_vcc *vcc) ...@@ -2645,7 +2624,7 @@ he_close(struct atm_vcc *vcc)
(void) he_readl_rsr0(he_dev, cid); (void) he_readl_rsr0(he_dev, cid);
#endif #endif
he_writel_mbox(he_dev, cid, RXCON_CLOSE); he_writel_mbox(he_dev, cid, RXCON_CLOSE);
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
timeout = schedule_timeout(30*HZ); timeout = schedule_timeout(30*HZ);
...@@ -2693,7 +2672,7 @@ he_close(struct atm_vcc *vcc) ...@@ -2693,7 +2672,7 @@ he_close(struct atm_vcc *vcc)
/* 2.3.1.1 generic close operations with flush */ /* 2.3.1.1 generic close operations with flush */
HE_SPIN_LOCK(he_dev, flags); spin_lock_irqsave(&he_dev->global_lock, flags);
he_writel_tsr4_upper(he_dev, TSR4_FLUSH_CONN, cid); he_writel_tsr4_upper(he_dev, TSR4_FLUSH_CONN, cid);
/* also clears TSR4_SESSION_ENDED */ /* also clears TSR4_SESSION_ENDED */
#ifdef CONFIG_IA64_SGI_SN2 #ifdef CONFIG_IA64_SGI_SN2
...@@ -2724,7 +2703,7 @@ he_close(struct atm_vcc *vcc) ...@@ -2724,7 +2703,7 @@ he_close(struct atm_vcc *vcc)
add_wait_queue(&he_vcc->tx_waitq, &wait); add_wait_queue(&he_vcc->tx_waitq, &wait);
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
__enqueue_tpd(he_dev, tpd, cid); __enqueue_tpd(he_dev, tpd, cid);
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
timeout = schedule_timeout(30*HZ); timeout = schedule_timeout(30*HZ);
...@@ -2736,7 +2715,7 @@ he_close(struct atm_vcc *vcc) ...@@ -2736,7 +2715,7 @@ he_close(struct atm_vcc *vcc)
goto close_tx_incomplete; goto close_tx_incomplete;
} }
HE_SPIN_LOCK(he_dev, flags); spin_lock_irqsave(&he_dev->global_lock, flags);
while (!((tsr4 = he_readl_tsr4(he_dev, cid)) & TSR4_SESSION_ENDED)) { while (!((tsr4 = he_readl_tsr4(he_dev, cid)) & TSR4_SESSION_ENDED)) {
HPRINTK("close tx cid 0x%x !TSR4_SESSION_ENDED (tsr4 = 0x%x)\n", cid, tsr4); HPRINTK("close tx cid 0x%x !TSR4_SESSION_ENDED (tsr4 = 0x%x)\n", cid, tsr4);
udelay(250); udelay(250);
...@@ -2761,7 +2740,7 @@ he_close(struct atm_vcc *vcc) ...@@ -2761,7 +2740,7 @@ he_close(struct atm_vcc *vcc)
he_dev->total_bw -= he_dev->cs_stper[reg].pcr; he_dev->total_bw -= he_dev->cs_stper[reg].pcr;
} }
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
HPRINTK("close tx cid 0x%x complete\n", cid); HPRINTK("close tx cid 0x%x complete\n", cid);
} }
...@@ -2818,7 +2797,7 @@ he_send(struct atm_vcc *vcc, struct sk_buff *skb) ...@@ -2818,7 +2797,7 @@ he_send(struct atm_vcc *vcc, struct sk_buff *skb)
return -EINVAL; return -EINVAL;
} }
#endif #endif
HE_SPIN_LOCK(he_dev, flags); spin_lock_irqsave(&he_dev->global_lock, flags);
tpd = __alloc_tpd(he_dev); tpd = __alloc_tpd(he_dev);
if (tpd == NULL) { if (tpd == NULL) {
...@@ -2827,7 +2806,7 @@ he_send(struct atm_vcc *vcc, struct sk_buff *skb) ...@@ -2827,7 +2806,7 @@ he_send(struct atm_vcc *vcc, struct sk_buff *skb)
else else
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
atomic_inc(&vcc->stats->tx_err); atomic_inc(&vcc->stats->tx_err);
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
return -ENOMEM; return -ENOMEM;
} }
...@@ -2869,7 +2848,7 @@ he_send(struct atm_vcc *vcc, struct sk_buff *skb) ...@@ -2869,7 +2848,7 @@ he_send(struct atm_vcc *vcc, struct sk_buff *skb)
else else
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
atomic_inc(&vcc->stats->tx_err); atomic_inc(&vcc->stats->tx_err);
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
return -ENOMEM; return -ENOMEM;
} }
tpd->status |= TPD_USERCELL; tpd->status |= TPD_USERCELL;
...@@ -2884,7 +2863,7 @@ he_send(struct atm_vcc *vcc, struct sk_buff *skb) ...@@ -2884,7 +2863,7 @@ he_send(struct atm_vcc *vcc, struct sk_buff *skb)
} }
tpd->iovec[slot-1].len |= TPD_LST; tpd->iovec[slot - 1].len |= TPD_LST;
#else #else
tpd->address0 = pci_map_single(he_dev->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE); tpd->address0 = pci_map_single(he_dev->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE);
tpd->length0 = skb->len | TPD_LST; tpd->length0 = skb->len | TPD_LST;
...@@ -2897,7 +2876,7 @@ he_send(struct atm_vcc *vcc, struct sk_buff *skb) ...@@ -2897,7 +2876,7 @@ he_send(struct atm_vcc *vcc, struct sk_buff *skb)
ATM_SKB(skb)->vcc = vcc; ATM_SKB(skb)->vcc = vcc;
__enqueue_tpd(he_dev, tpd, cid); __enqueue_tpd(he_dev, tpd, cid);
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
atomic_inc(&vcc->stats->tx); atomic_inc(&vcc->stats->tx);
...@@ -2919,7 +2898,7 @@ he_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void *arg) ...@@ -2919,7 +2898,7 @@ he_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void *arg)
copy_from_user(&reg, (struct he_ioctl_reg *) arg, copy_from_user(&reg, (struct he_ioctl_reg *) arg,
sizeof(struct he_ioctl_reg)); sizeof(struct he_ioctl_reg));
HE_SPIN_LOCK(he_dev, flags); spin_lock_irqsave(&he_dev->global_lock, flags);
switch (reg.type) { switch (reg.type) {
case HE_REGTYPE_PCI: case HE_REGTYPE_PCI:
reg.val = he_readl(he_dev, reg.addr); reg.val = he_readl(he_dev, reg.addr);
...@@ -2940,7 +2919,7 @@ he_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void *arg) ...@@ -2940,7 +2919,7 @@ he_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void *arg)
err = -EINVAL; err = -EINVAL;
break; break;
} }
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
if (err == 0) if (err == 0)
copy_to_user((struct he_ioctl_reg *) arg, &reg, copy_to_user((struct he_ioctl_reg *) arg, &reg,
sizeof(struct he_ioctl_reg)); sizeof(struct he_ioctl_reg));
...@@ -2966,12 +2945,12 @@ he_phy_put(struct atm_dev *atm_dev, unsigned char val, unsigned long addr) ...@@ -2966,12 +2945,12 @@ he_phy_put(struct atm_dev *atm_dev, unsigned char val, unsigned long addr)
HPRINTK("phy_put(val 0x%x, addr 0x%lx)\n", val, addr); HPRINTK("phy_put(val 0x%x, addr 0x%lx)\n", val, addr);
HE_SPIN_LOCK(he_dev, flags); spin_lock_irqsave(&he_dev->global_lock, flags);
he_writel(he_dev, val, FRAMER + (addr*4)); he_writel(he_dev, val, FRAMER + (addr*4));
#ifdef CONFIG_IA64_SGI_SN2 #ifdef CONFIG_IA64_SGI_SN2
(void) he_readl(he_dev, FRAMER + (addr*4)); (void) he_readl(he_dev, FRAMER + (addr*4));
#endif #endif
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
} }
...@@ -2982,9 +2961,9 @@ he_phy_get(struct atm_dev *atm_dev, unsigned long addr) ...@@ -2982,9 +2961,9 @@ he_phy_get(struct atm_dev *atm_dev, unsigned long addr)
struct he_dev *he_dev = HE_DEV(atm_dev); struct he_dev *he_dev = HE_DEV(atm_dev);
unsigned reg; unsigned reg;
HE_SPIN_LOCK(he_dev, flags); spin_lock_irqsave(&he_dev->global_lock, flags);
reg = he_readl(he_dev, FRAMER + (addr*4)); reg = he_readl(he_dev, FRAMER + (addr*4));
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
HPRINTK("phy_get(addr 0x%lx) =0x%x\n", addr, reg); HPRINTK("phy_get(addr 0x%lx) =0x%x\n", addr, reg);
return reg; return reg;
...@@ -3015,12 +2994,12 @@ he_proc_read(struct atm_dev *dev, loff_t *pos, char *page) ...@@ -3015,12 +2994,12 @@ he_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
if (!left--) if (!left--)
return sprintf(page, "Mismatched Cells VPI/VCI Not Open Dropped Cells RCM Dropped Cells\n"); return sprintf(page, "Mismatched Cells VPI/VCI Not Open Dropped Cells RCM Dropped Cells\n");
HE_SPIN_LOCK(he_dev, flags); spin_lock_irqsave(&he_dev->global_lock, flags);
mcc += he_readl(he_dev, MCC); mcc += he_readl(he_dev, MCC);
oec += he_readl(he_dev, OEC); oec += he_readl(he_dev, OEC);
dcc += he_readl(he_dev, DCC); dcc += he_readl(he_dev, DCC);
cec += he_readl(he_dev, CEC); cec += he_readl(he_dev, CEC);
HE_SPIN_UNLOCK(he_dev, flags); spin_unlock_irqrestore(&he_dev->global_lock, flags);
if (!left--) if (!left--)
return sprintf(page, "%16ld %16ld %13ld %17ld\n\n", return sprintf(page, "%16ld %16ld %13ld %17ld\n\n",
...@@ -3090,32 +3069,31 @@ read_prom_byte(struct he_dev *he_dev, int addr) ...@@ -3090,32 +3069,31 @@ read_prom_byte(struct he_dev *he_dev, int addr)
he_writel(he_dev, val, HOST_CNTL); he_writel(he_dev, val, HOST_CNTL);
/* Send READ instruction */ /* Send READ instruction */
for (i=0; i<sizeof(readtab)/sizeof(readtab[0]); i++) { for (i = 0; i < sizeof(readtab)/sizeof(readtab[0]); i++) {
he_writel(he_dev, val | readtab[i], HOST_CNTL); he_writel(he_dev, val | readtab[i], HOST_CNTL);
udelay(EEPROM_DELAY); udelay(EEPROM_DELAY);
} }
/* Next, we need to send the byte address to read from */ /* Next, we need to send the byte address to read from */
for (i=7; i>=0; i--) { for (i = 7; i >= 0; i--) {
he_writel(he_dev, val | clocktab[j++] | (((addr >> i) & 1) << 9), HOST_CNTL); he_writel(he_dev, val | clocktab[j++] | (((addr >> i) & 1) << 9), HOST_CNTL);
udelay(EEPROM_DELAY); udelay(EEPROM_DELAY);
he_writel(he_dev, val | clocktab[j++] | (((addr >> i) & 1) << 9), HOST_CNTL); he_writel(he_dev, val | clocktab[j++] | (((addr >> i) & 1) << 9), HOST_CNTL);
udelay(EEPROM_DELAY); udelay(EEPROM_DELAY);
} }
j=0; j = 0;
val &= 0xFFFFF7FF; /* Turn off write enable */ val &= 0xFFFFF7FF; /* Turn off write enable */
he_writel(he_dev, val, HOST_CNTL); he_writel(he_dev, val, HOST_CNTL);
/* Now, we can read data from the EEPROM by clocking it in */ /* Now, we can read data from the EEPROM by clocking it in */
for (i=7; i>=0; i--) { for (i = 7; i >= 0; i--) {
he_writel(he_dev, val | clocktab[j++], HOST_CNTL); he_writel(he_dev, val | clocktab[j++], HOST_CNTL);
udelay(EEPROM_DELAY); udelay(EEPROM_DELAY);
tmp_read = he_readl(he_dev, HOST_CNTL); tmp_read = he_readl(he_dev, HOST_CNTL);
byte_read |= (unsigned char) byte_read |= (unsigned char)
((tmp_read & ID_DOUT) ((tmp_read & ID_DOUT) >> ID_DOFFSET << i);
>> ID_DOFFSET << i);
he_writel(he_dev, val | clocktab[j++], HOST_CNTL); he_writel(he_dev, val | clocktab[j++], HOST_CNTL);
udelay(EEPROM_DELAY); udelay(EEPROM_DELAY);
} }
...@@ -3123,7 +3101,7 @@ read_prom_byte(struct he_dev *he_dev, int addr) ...@@ -3123,7 +3101,7 @@ read_prom_byte(struct he_dev *he_dev, int addr)
he_writel(he_dev, val | ID_CS, HOST_CNTL); he_writel(he_dev, val | ID_CS, HOST_CNTL);
udelay(EEPROM_DELAY); udelay(EEPROM_DELAY);
return (byte_read); return byte_read;
} }
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
...@@ -6,7 +6,8 @@ ...@@ -6,7 +6,8 @@
* Microgate and SyncLink are registered trademarks of Microgate Corporation * Microgate and SyncLink are registered trademarks of Microgate Corporation
* *
* Adapted from ppp.c, written by Michael Callahan <callahan@maths.ox.ac.uk>, * Adapted from ppp.c, written by Michael Callahan <callahan@maths.ox.ac.uk>,
* Al Longyear <longyear@netcom.com>, Paul Mackerras <Paul.Mackerras@cs.anu.edu.au> * Al Longyear <longyear@netcom.com>,
* Paul Mackerras <Paul.Mackerras@cs.anu.edu.au>
* *
* Original release 01/11/99 * Original release 01/11/99
* $Id: n_hdlc.c,v 4.8 2003/05/06 21:18:51 paulkf Exp $ * $Id: n_hdlc.c,v 4.8 2003/05/06 21:18:51 paulkf Exp $
...@@ -96,32 +97,19 @@ ...@@ -96,32 +97,19 @@
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/in.h> #include <linux/in.h>
#include <linux/ioctl.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/string.h> /* used in new tty drivers */ #include <linux/string.h> /* used in new tty drivers */
#include <linux/signal.h> /* used in new tty drivers */ #include <linux/signal.h> /* used in new tty drivers */
#include <linux/if.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/termios.h> #include <asm/termios.h>
#include <linux/if.h>
#include <linux/ioctl.h>
#ifdef CONFIG_KERNELD
#include <linux/kerneld.h>
#endif
#define GET_USER(error,value,addr) error = get_user(value,addr)
#define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0
#define PUT_USER(error,value,addr) error = put_user(value,addr)
#define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0
#include <asm/uaccess.h> #include <asm/uaccess.h>
typedef ssize_t rw_ret_t;
typedef size_t rw_count_t;
/* /*
* Buffers for individual HDLC frames * Buffers for individual HDLC frames
*/ */
...@@ -130,91 +118,90 @@ typedef size_t rw_count_t; ...@@ -130,91 +118,90 @@ typedef size_t rw_count_t;
#define MAX_RX_BUF_COUNT 60 #define MAX_RX_BUF_COUNT 60
#define DEFAULT_TX_BUF_COUNT 1 #define DEFAULT_TX_BUF_COUNT 1
struct n_hdlc_buf {
typedef struct _n_hdlc_buf struct n_hdlc_buf *link;
{
struct _n_hdlc_buf *link;
int count; int count;
char buf[1]; char buf[1];
} N_HDLC_BUF; };
#define N_HDLC_BUF_SIZE (sizeof(N_HDLC_BUF)+maxframe) #define N_HDLC_BUF_SIZE (sizeof(struct n_hdlc_buf) + maxframe)
typedef struct _n_hdlc_buf_list struct n_hdlc_buf_list {
{ struct n_hdlc_buf *head;
N_HDLC_BUF *head; struct n_hdlc_buf *tail;
N_HDLC_BUF *tail;
int count; int count;
spinlock_t spinlock; spinlock_t spinlock;
};
} N_HDLC_BUF_LIST; /**
* struct n_hdlc - per device instance data structure
/* * @magic - magic value for structure
* Per device instance data structure * @flags - miscellaneous control flags
* @tty - ptr to TTY structure
* @backup_tty - TTY to use if tty gets closed
* @tbusy - reentrancy flag for tx wakeup code
* @woke_up - FIXME: describe this field
* @tbuf - currently transmitting tx buffer
* @tx_buf_list - list of pending transmit frame buffers
* @rx_buf_list - list of received frame buffers
* @tx_free_buf_list - list unused transmit frame buffers
* @rx_free_buf_list - list unused received frame buffers
*/ */
struct n_hdlc { struct n_hdlc {
int magic; /* magic value for structure */ int magic;
__u32 flags; /* miscellaneous control flags */ __u32 flags;
struct tty_struct *tty;
struct tty_struct *tty; /* ptr to TTY structure */ struct tty_struct *backup_tty;
struct tty_struct *backup_tty; /* TTY to use if tty gets closed */ int tbusy;
int tbusy; /* reentrancy flag for tx wakeup code */
int woke_up; int woke_up;
N_HDLC_BUF *tbuf; /* currently transmitting tx buffer */ struct n_hdlc_buf *tbuf;
N_HDLC_BUF_LIST tx_buf_list; /* list of pending transmit frame buffers */ struct n_hdlc_buf_list tx_buf_list;
N_HDLC_BUF_LIST rx_buf_list; /* list of received frame buffers */ struct n_hdlc_buf_list rx_buf_list;
N_HDLC_BUF_LIST tx_free_buf_list; /* list unused transmit frame buffers */ struct n_hdlc_buf_list tx_free_buf_list;
N_HDLC_BUF_LIST rx_free_buf_list; /* list unused received frame buffers */ struct n_hdlc_buf_list rx_free_buf_list;
}; };
/* /*
* HDLC buffer list manipulation functions * HDLC buffer list manipulation functions
*/ */
static void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list); static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list);
static void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf); static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list); struct n_hdlc_buf *buf);
static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *list);
/* Local functions */ /* Local functions */
static struct n_hdlc *n_hdlc_alloc (void); static struct n_hdlc *n_hdlc_alloc (void);
MODULE_PARM(debuglevel, "i");
MODULE_PARM(maxframe, "i");
/* debug level can be set by insmod for debugging purposes */ /* debug level can be set by insmod for debugging purposes */
#define DEBUG_LEVEL_INFO 1 #define DEBUG_LEVEL_INFO 1
static int debuglevel; static int debuglevel;
/* max frame size for memory allocations */ /* max frame size for memory allocations */
static ssize_t maxframe=4096; static ssize_t maxframe = 4096;
/* TTY callbacks */ /* TTY callbacks */
static rw_ret_t n_hdlc_tty_read(struct tty_struct *, static int n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
struct file *, __u8 *, rw_count_t); __u8 *buf, size_t nr);
static rw_ret_t n_hdlc_tty_write(struct tty_struct *, static int n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
struct file *, const __u8 *, rw_count_t); const __u8 *buf, size_t nr);
static int n_hdlc_tty_ioctl(struct tty_struct *, static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
struct file *, unsigned int, unsigned long); unsigned int cmd, unsigned long arg);
static unsigned int n_hdlc_tty_poll (struct tty_struct *tty, struct file *filp, static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
poll_table * wait); poll_table *wait);
static int n_hdlc_tty_open (struct tty_struct *); static int n_hdlc_tty_open(struct tty_struct *tty);
static void n_hdlc_tty_close (struct tty_struct *); static void n_hdlc_tty_close(struct tty_struct *tty);
static int n_hdlc_tty_room (struct tty_struct *tty); static int n_hdlc_tty_room(struct tty_struct *tty);
static void n_hdlc_tty_receive (struct tty_struct *tty, static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp,
const __u8 * cp, char *fp, int count); char *fp, int count);
static void n_hdlc_tty_wakeup (struct tty_struct *tty); static void n_hdlc_tty_wakeup(struct tty_struct *tty);
#define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f))) #define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f)))
#define tty2n_hdlc(tty) ((struct n_hdlc *) ((tty)->disc_data)) #define tty2n_hdlc(tty) ((struct n_hdlc *) ((tty)->disc_data))
#define n_hdlc2tty(n_hdlc) ((n_hdlc)->tty) #define n_hdlc2tty(n_hdlc) ((n_hdlc)->tty)
/* Define this string only once for all macro invocations */
static char szVersion[] = HDLC_VERSION;
static struct tty_ldisc n_hdlc_ldisc = { static struct tty_ldisc n_hdlc_ldisc = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC, .magic = TTY_LDISC_MAGIC,
...@@ -230,15 +217,14 @@ static struct tty_ldisc n_hdlc_ldisc = { ...@@ -230,15 +217,14 @@ static struct tty_ldisc n_hdlc_ldisc = {
.write_wakeup = n_hdlc_tty_wakeup, .write_wakeup = n_hdlc_tty_wakeup,
}; };
/* n_hdlc_release() /**
* * n_hdlc_release - release an n_hdlc per device line discipline info structure
* release an n_hdlc per device line discipline info structure * @n_hdlc - per device line discipline info structure
*
*/ */
static void n_hdlc_release (struct n_hdlc *n_hdlc) static void n_hdlc_release(struct n_hdlc *n_hdlc)
{ {
struct tty_struct *tty = n_hdlc2tty (n_hdlc); struct tty_struct *tty = n_hdlc2tty (n_hdlc);
N_HDLC_BUF *buf; struct n_hdlc_buf *buf;
if (debuglevel >= DEBUG_LEVEL_INFO) if (debuglevel >= DEBUG_LEVEL_INFO)
printk("%s(%d)n_hdlc_release() called\n",__FILE__,__LINE__); printk("%s(%d)n_hdlc_release() called\n",__FILE__,__LINE__);
...@@ -285,7 +271,9 @@ static void n_hdlc_release (struct n_hdlc *n_hdlc) ...@@ -285,7 +271,9 @@ static void n_hdlc_release (struct n_hdlc *n_hdlc)
} /* end of n_hdlc_release() */ } /* end of n_hdlc_release() */
/* n_hdlc_tty_close() /**
* n_hdlc_tty_close - line discipline close
* @tty - pointer to tty info structure
* *
* Called when the line discipline is changed to something * Called when the line discipline is changed to something
* else, the tty is closed, or the tty detects a hangup. * else, the tty is closed, or the tty detects a hangup.
...@@ -322,12 +310,11 @@ static void n_hdlc_tty_close(struct tty_struct *tty) ...@@ -322,12 +310,11 @@ static void n_hdlc_tty_close(struct tty_struct *tty)
} /* end of n_hdlc_tty_close() */ } /* end of n_hdlc_tty_close() */
/* n_hdlc_tty_open /**
* * n_hdlc_tty_open - called when line discipline changed to n_hdlc
* called when line discipline changed to n_hdlc * @tty - pointer to tty info structure
* *
* Arguments: tty pointer to tty info structure * Returns 0 if success, otherwise error code
* Return Value: 0 if success, otherwise error code
*/ */
static int n_hdlc_tty_open (struct tty_struct *tty) static int n_hdlc_tty_open (struct tty_struct *tty)
{ {
...@@ -373,22 +360,20 @@ static int n_hdlc_tty_open (struct tty_struct *tty) ...@@ -373,22 +360,20 @@ static int n_hdlc_tty_open (struct tty_struct *tty)
} /* end of n_tty_hdlc_open() */ } /* end of n_tty_hdlc_open() */
/* n_hdlc_send_frames() /**
* n_hdlc_send_frames - send frames on pending send buffer list
* @n_hdlc - pointer to ldisc instance data
* @tty - pointer to tty instance data
* *
* send frames on pending send buffer list until the * Send frames on pending send buffer list until the driver does not accept a
* driver does not accept a frame (busy) * frame (busy) this function is called after adding a frame to the send buffer
* this function is called after adding a frame to the * list and by the tty wakeup callback.
* send buffer list and by the tty wakeup callback
*
* Arguments: n_hdlc pointer to ldisc instance data
* tty pointer to tty instance data
* Return Value: None
*/ */
static void n_hdlc_send_frames (struct n_hdlc *n_hdlc, struct tty_struct *tty) static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
{ {
register int actual; register int actual;
unsigned long flags; unsigned long flags;
N_HDLC_BUF *tbuf; struct n_hdlc_buf *tbuf;
if (debuglevel >= DEBUG_LEVEL_INFO) if (debuglevel >= DEBUG_LEVEL_INFO)
printk("%s(%d)n_hdlc_send_frames() called\n",__FILE__,__LINE__); printk("%s(%d)n_hdlc_send_frames() called\n",__FILE__,__LINE__);
...@@ -431,7 +416,7 @@ static void n_hdlc_send_frames (struct n_hdlc *n_hdlc, struct tty_struct *tty) ...@@ -431,7 +416,7 @@ static void n_hdlc_send_frames (struct n_hdlc *n_hdlc, struct tty_struct *tty)
__FILE__,__LINE__,tbuf); __FILE__,__LINE__,tbuf);
/* free current transmit buffer */ /* free current transmit buffer */
n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,tbuf); n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, tbuf);
/* this tx buffer is done */ /* this tx buffer is done */
n_hdlc->tbuf = NULL; n_hdlc->tbuf = NULL;
...@@ -469,17 +454,15 @@ static void n_hdlc_send_frames (struct n_hdlc *n_hdlc, struct tty_struct *tty) ...@@ -469,17 +454,15 @@ static void n_hdlc_send_frames (struct n_hdlc *n_hdlc, struct tty_struct *tty)
} /* end of n_hdlc_send_frames() */ } /* end of n_hdlc_send_frames() */
/* n_hdlc_tty_wakeup() /**
* n_hdlc_tty_wakeup - Callback for transmit wakeup
* @tty - pointer to associated tty instance data
* *
* Callback for transmit wakeup. Called when low level * Called when low level device driver can accept more send data.
* device driver can accept more send data.
*
* Arguments: tty pointer to associated tty instance data
* Return Value: None
*/ */
static void n_hdlc_tty_wakeup (struct tty_struct *tty) static void n_hdlc_tty_wakeup(struct tty_struct *tty)
{ {
struct n_hdlc *n_hdlc = tty2n_hdlc (tty); struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
if (debuglevel >= DEBUG_LEVEL_INFO) if (debuglevel >= DEBUG_LEVEL_INFO)
printk("%s(%d)n_hdlc_tty_wakeup() called\n",__FILE__,__LINE__); printk("%s(%d)n_hdlc_tty_wakeup() called\n",__FILE__,__LINE__);
...@@ -496,16 +479,14 @@ static void n_hdlc_tty_wakeup (struct tty_struct *tty) ...@@ -496,16 +479,14 @@ static void n_hdlc_tty_wakeup (struct tty_struct *tty)
} /* end of n_hdlc_tty_wakeup() */ } /* end of n_hdlc_tty_wakeup() */
/* n_hdlc_tty_room() /**
* * n_hdlc_tty_room - Return the amount of space left in the receiver's buffer
* Callback function from tty driver. Return the amount of * @tty - pointer to associated tty instance data
* space left in the receiver's buffer to decide if remote
* transmitter is to be throttled.
* *
* Arguments: tty pointer to associated tty instance data * Callback function from tty driver. Return the amount of space left in the
* Return Value: number of bytes left in receive buffer * receiver's buffer to decide if remote transmitter is to be throttled.
*/ */
static int n_hdlc_tty_room (struct tty_struct *tty) static int n_hdlc_tty_room(struct tty_struct *tty)
{ {
if (debuglevel >= DEBUG_LEVEL_INFO) if (debuglevel >= DEBUG_LEVEL_INFO)
printk("%s(%d)n_hdlc_tty_room() called\n",__FILE__,__LINE__); printk("%s(%d)n_hdlc_tty_room() called\n",__FILE__,__LINE__);
...@@ -514,23 +495,21 @@ static int n_hdlc_tty_room (struct tty_struct *tty) ...@@ -514,23 +495,21 @@ static int n_hdlc_tty_room (struct tty_struct *tty)
return 65536; return 65536;
} /* end of n_hdlc_tty_root() */ } /* end of n_hdlc_tty_root() */
/* n_hdlc_tty_receive() /**
* n_hdlc_tty_receive - Called by tty driver when receive data is available
* @tty - pointer to tty instance data
* @data - pointer to received data
* @flags - pointer to flags for data
* @count - count of received data in bytes
* *
* Called by tty low level driver when receive data is * Called by tty low level driver when receive data is available. Data is
* available. Data is interpreted as one HDLC frame. * interpreted as one HDLC frame.
*
* Arguments: tty pointer to tty isntance data
* data pointer to received data
* flags pointer to flags for data
* count count of received data in bytes
*
* Return Value: None
*/ */
static void n_hdlc_tty_receive(struct tty_struct *tty, static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
const __u8 * data, char *flags, int count) char *flags, int count)
{ {
register struct n_hdlc *n_hdlc = tty2n_hdlc (tty); register struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
register N_HDLC_BUF *buf; register struct n_hdlc_buf *buf;
if (debuglevel >= DEBUG_LEVEL_INFO) if (debuglevel >= DEBUG_LEVEL_INFO)
printk("%s(%d)n_hdlc_tty_receive() called count=%d\n", printk("%s(%d)n_hdlc_tty_receive() called count=%d\n",
...@@ -560,7 +539,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, ...@@ -560,7 +539,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty,
/* no buffers in free list, attempt to allocate another rx buffer */ /* no buffers in free list, attempt to allocate another rx buffer */
/* unless the maximum count has been reached */ /* unless the maximum count has been reached */
if (n_hdlc->rx_buf_list.count < MAX_RX_BUF_COUNT) if (n_hdlc->rx_buf_list.count < MAX_RX_BUF_COUNT)
buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_ATOMIC); buf = kmalloc(N_HDLC_BUF_SIZE, GFP_ATOMIC);
} }
if (!buf) { if (!buf) {
...@@ -575,7 +554,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, ...@@ -575,7 +554,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty,
buf->count=count; buf->count=count;
/* add HDLC buffer to list of received frames */ /* add HDLC buffer to list of received frames */
n_hdlc_buf_put(&n_hdlc->rx_buf_list,buf); n_hdlc_buf_put(&n_hdlc->rx_buf_list, buf);
/* wake up any blocked reads and perform async signalling */ /* wake up any blocked reads and perform async signalling */
wake_up_interruptible (&tty->read_wait); wake_up_interruptible (&tty->read_wait);
...@@ -584,28 +563,22 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, ...@@ -584,28 +563,22 @@ static void n_hdlc_tty_receive(struct tty_struct *tty,
} /* end of n_hdlc_tty_receive() */ } /* end of n_hdlc_tty_receive() */
/* n_hdlc_tty_read() /**
* * n_hdlc_tty_read - Called to retreive one frame of data (if available)
* Called to retreive one frame of data (if available) * @tty - pointer to tty instance data
* * @file - pointer to open file object
* Arguments: * @buf - pointer to returned data buffer
* * @nr - size of returned data buffer
* tty pointer to tty instance data
* file pointer to open file object
* buf pointer to returned data buffer
* nr size of returned data buffer
* *
* Return Value: * Returns the number of bytes returned or error code.
*
* Number of bytes returned or error code
*/ */
static rw_ret_t n_hdlc_tty_read (struct tty_struct *tty, static int n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
struct file *file, __u8 * buf, rw_count_t nr) __u8 *buf, size_t nr)
{ {
struct n_hdlc *n_hdlc = tty2n_hdlc(tty); struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
int error; int error;
rw_ret_t ret; int ret;
N_HDLC_BUF *rbuf; struct n_hdlc_buf *rbuf;
if (debuglevel >= DEBUG_LEVEL_INFO) if (debuglevel >= DEBUG_LEVEL_INFO)
printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__,__LINE__); printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__,__LINE__);
...@@ -644,16 +617,15 @@ static rw_ret_t n_hdlc_tty_read (struct tty_struct *tty, ...@@ -644,16 +617,15 @@ static rw_ret_t n_hdlc_tty_read (struct tty_struct *tty,
return -EINTR; return -EINTR;
} }
if (rbuf->count > nr) { if (rbuf->count > nr)
/* frame too large for caller's buffer (discard frame) */ /* frame too large for caller's buffer (discard frame) */
ret = (rw_ret_t)-EOVERFLOW; ret = -EOVERFLOW;
} else { else {
/* Copy the data to the caller's buffer */ /* Copy the data to the caller's buffer */
COPY_TO_USER(error,buf,rbuf->buf,rbuf->count); if (copy_to_user(buf, rbuf->buf, rbuf->count))
if (error) ret = -EFAULT;
ret = (rw_ret_t)error;
else else
ret = (rw_ret_t)rbuf->count; ret = rbuf->count;
} }
/* return HDLC buffer to free list unless the free list */ /* return HDLC buffer to free list unless the free list */
...@@ -668,24 +640,22 @@ static rw_ret_t n_hdlc_tty_read (struct tty_struct *tty, ...@@ -668,24 +640,22 @@ static rw_ret_t n_hdlc_tty_read (struct tty_struct *tty,
} /* end of n_hdlc_tty_read() */ } /* end of n_hdlc_tty_read() */
/* n_hdlc_tty_write() /**
* * n_hdlc_tty_write - write a single frame of data to device
* write a single frame of data to device * @tty - pointer to associated tty device instance data
* * @file - pointer to file object data
* Arguments: tty pointer to associated tty device instance data * @data - pointer to transmit data (one frame)
* file pointer to file object data * @count - size of transmit frame in bytes
* data pointer to transmit data (one frame)
* count size of transmit frame in bytes
* *
* Return Value: number of bytes written (or error code) * Returns the number of bytes written (or error code).
*/ */
static rw_ret_t n_hdlc_tty_write (struct tty_struct *tty, struct file *file, static int n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
const __u8 * data, rw_count_t count) const __u8 *data, size_t count)
{ {
struct n_hdlc *n_hdlc = tty2n_hdlc (tty); struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
int error = 0; int error = 0;
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
N_HDLC_BUF *tbuf; struct n_hdlc_buf *tbuf;
if (debuglevel >= DEBUG_LEVEL_INFO) if (debuglevel >= DEBUG_LEVEL_INFO)
printk("%s(%d)n_hdlc_tty_write() called count=%d\n", printk("%s(%d)n_hdlc_tty_write() called count=%d\n",
...@@ -735,10 +705,10 @@ static rw_ret_t n_hdlc_tty_write (struct tty_struct *tty, struct file *file, ...@@ -735,10 +705,10 @@ static rw_ret_t n_hdlc_tty_write (struct tty_struct *tty, struct file *file,
if (!error) { if (!error) {
/* Retrieve the user's buffer */ /* Retrieve the user's buffer */
COPY_FROM_USER (error, tbuf->buf, data, count); if (copy_from_user(tbuf->buf, data, count)) {
if (error) {
/* return tx buffer to free list */ /* return tx buffer to free list */
n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,tbuf); n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,tbuf);
error = -EFAULT;
} else { } else {
/* Send the data */ /* Send the data */
tbuf->count = error = count; tbuf->count = error = count;
...@@ -751,20 +721,16 @@ static rw_ret_t n_hdlc_tty_write (struct tty_struct *tty, struct file *file, ...@@ -751,20 +721,16 @@ static rw_ret_t n_hdlc_tty_write (struct tty_struct *tty, struct file *file,
} /* end of n_hdlc_tty_write() */ } /* end of n_hdlc_tty_write() */
/* n_hdlc_tty_ioctl() /**
* n_hdlc_tty_ioctl - process IOCTL system call for the tty device.
* @tty - pointer to tty instance data
* @file - pointer to open file object for device
* @cmd - IOCTL command code
* @arg - argument for IOCTL call (cmd dependent)
* *
* Process IOCTL system call for the tty device. * Returns command dependent result.
*
* Arguments:
*
* tty pointer to tty instance data
* file pointer to open file object for device
* cmd IOCTL command code
* arg argument for IOCTL call (cmd dependent)
*
* Return Value: Command dependent
*/ */
static int n_hdlc_tty_ioctl (struct tty_struct *tty, struct file * file, static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
struct n_hdlc *n_hdlc = tty2n_hdlc (tty); struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
...@@ -790,7 +756,7 @@ static int n_hdlc_tty_ioctl (struct tty_struct *tty, struct file * file, ...@@ -790,7 +756,7 @@ static int n_hdlc_tty_ioctl (struct tty_struct *tty, struct file * file,
else else
count = 0; count = 0;
spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags); spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags);
PUT_USER (error, count, (int *) arg); error = put_user(count, (int *)arg);
break; break;
case TIOCOUTQ: case TIOCOUTQ:
...@@ -802,7 +768,7 @@ static int n_hdlc_tty_ioctl (struct tty_struct *tty, struct file * file, ...@@ -802,7 +768,7 @@ static int n_hdlc_tty_ioctl (struct tty_struct *tty, struct file * file,
if (n_hdlc->tx_buf_list.head) if (n_hdlc->tx_buf_list.head)
count += n_hdlc->tx_buf_list.head->count; count += n_hdlc->tx_buf_list.head->count;
spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags); spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags);
PUT_USER (error, count, (int*)arg); error = put_user(count, (int*)arg);
break; break;
default: default:
...@@ -813,24 +779,18 @@ static int n_hdlc_tty_ioctl (struct tty_struct *tty, struct file * file, ...@@ -813,24 +779,18 @@ static int n_hdlc_tty_ioctl (struct tty_struct *tty, struct file * file,
} /* end of n_hdlc_tty_ioctl() */ } /* end of n_hdlc_tty_ioctl() */
/* n_hdlc_tty_poll() /**
* * n_hdlc_tty_poll - TTY callback for poll system call
* TTY callback for poll system call. Determine which * @tty - pointer to tty instance data
* operations (read/write) will not block and return * @filp - pointer to open file object for device
* info to caller. * @poll_table - wait queue for operations
* *
* Arguments: * Determine which operations (read/write) will not block and return info
* * to caller.
* tty pointer to tty instance data * Returns a bit mask containing info on which ops will not block.
* filp pointer to open file object for device
* poll_table wait queue for operations
*
* Return Value:
*
* bit mask containing info on which ops will not block
*/ */
static unsigned int n_hdlc_tty_poll (struct tty_struct *tty, static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
struct file *filp, poll_table * wait) poll_table *wait)
{ {
struct n_hdlc *n_hdlc = tty2n_hdlc (tty); struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
unsigned int mask = 0; unsigned int mask = 0;
...@@ -858,20 +818,17 @@ static unsigned int n_hdlc_tty_poll (struct tty_struct *tty, ...@@ -858,20 +818,17 @@ static unsigned int n_hdlc_tty_poll (struct tty_struct *tty,
return mask; return mask;
} /* end of n_hdlc_tty_poll() */ } /* end of n_hdlc_tty_poll() */
/* n_hdlc_alloc() /**
* * n_hdlc_alloc - allocate an n_hdlc instance data structure
* Allocate an n_hdlc instance data structure
* *
* Arguments: None * Returns a pointer to newly created structure if success, otherwise %NULL
* Return Value: pointer to structure if success, otherwise 0
*/ */
static struct n_hdlc *n_hdlc_alloc (void) static struct n_hdlc *n_hdlc_alloc(void)
{ {
struct n_hdlc *n_hdlc; struct n_hdlc_buf *buf;
N_HDLC_BUF *buf;
int i; int i;
struct n_hdlc *n_hdlc = kmalloc(sizeof(*n_hdlc), GFP_KERNEL);
n_hdlc = (struct n_hdlc *)kmalloc(sizeof(struct n_hdlc), GFP_KERNEL);
if (!n_hdlc) if (!n_hdlc)
return 0; return 0;
...@@ -884,7 +841,7 @@ static struct n_hdlc *n_hdlc_alloc (void) ...@@ -884,7 +841,7 @@ static struct n_hdlc *n_hdlc_alloc (void)
/* allocate free rx buffer list */ /* allocate free rx buffer list */
for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) { for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) {
buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_KERNEL); buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
if (buf) if (buf)
n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,buf); n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,buf);
else if (debuglevel >= DEBUG_LEVEL_INFO) else if (debuglevel >= DEBUG_LEVEL_INFO)
...@@ -893,7 +850,7 @@ static struct n_hdlc *n_hdlc_alloc (void) ...@@ -893,7 +850,7 @@ static struct n_hdlc *n_hdlc_alloc (void)
/* allocate free tx buffer list */ /* allocate free tx buffer list */
for(i=0;i<DEFAULT_TX_BUF_COUNT;i++) { for(i=0;i<DEFAULT_TX_BUF_COUNT;i++) {
buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_KERNEL); buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
if (buf) if (buf)
n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,buf); n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,buf);
else if (debuglevel >= DEBUG_LEVEL_INFO) else if (debuglevel >= DEBUG_LEVEL_INFO)
...@@ -908,31 +865,23 @@ static struct n_hdlc *n_hdlc_alloc (void) ...@@ -908,31 +865,23 @@ static struct n_hdlc *n_hdlc_alloc (void)
} /* end of n_hdlc_alloc() */ } /* end of n_hdlc_alloc() */
/* n_hdlc_buf_list_init() /**
* * n_hdlc_buf_list_init - initialize specified HDLC buffer list
* initialize specified HDLC buffer list * @list - pointer to buffer list
*
* Arguments: list pointer to buffer list
* Return Value: None
*/ */
static void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list) static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list)
{ {
memset(list,0,sizeof(N_HDLC_BUF_LIST)); memset(list, 0, sizeof(*list));
spin_lock_init(&list->spinlock); spin_lock_init(&list->spinlock);
} /* end of n_hdlc_buf_list_init() */ } /* end of n_hdlc_buf_list_init() */
/* n_hdlc_buf_put() /**
* * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list
* add specified HDLC buffer to tail of specified list * @list - pointer to buffer list
* * @buf - pointer to buffer
* Arguments:
*
* list pointer to buffer list
* buf pointer to buffer
*
* Return Value: None
*/ */
static void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf) static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
struct n_hdlc_buf *buf)
{ {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&list->spinlock,flags); spin_lock_irqsave(&list->spinlock,flags);
...@@ -949,23 +898,18 @@ static void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf) ...@@ -949,23 +898,18 @@ static void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf)
} /* end of n_hdlc_buf_put() */ } /* end of n_hdlc_buf_put() */
/* n_hdlc_buf_get() /**
* * n_hdlc_buf_get - remove and return an HDLC buffer from list
* remove and return an HDLC buffer from the * @list - pointer to HDLC buffer list
* head of the specified HDLC buffer list
*
* Arguments:
*
* list pointer to HDLC buffer list
* *
* Return Value: * Remove and return an HDLC buffer from the head of the specified HDLC buffer
* * list.
* pointer to HDLC buffer if available, otherwise NULL * Returns a pointer to HDLC buffer if available, otherwise %NULL.
*/ */
static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list) static struct n_hdlc_buf* n_hdlc_buf_get(struct n_hdlc_buf_list *list)
{ {
unsigned long flags; unsigned long flags;
N_HDLC_BUF *buf; struct n_hdlc_buf *buf;
spin_lock_irqsave(&list->spinlock,flags); spin_lock_irqsave(&list->spinlock,flags);
buf = list->head; buf = list->head;
...@@ -981,42 +925,60 @@ static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list) ...@@ -981,42 +925,60 @@ static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list)
} /* end of n_hdlc_buf_get() */ } /* end of n_hdlc_buf_get() */
static char hdlc_banner[] __initdata =
KERN_INFO "HDLC line discipline: version " HDLC_VERSION
", maxframe=%u\n";
static char hdlc_register_ok[] __initdata =
KERN_INFO "N_HDLC line discipline registered.\n";
static char hdlc_register_fail[] __initdata =
KERN_ERR "error registering line discipline: %d\n";
static char hdlc_init_fail[] __initdata =
KERN_INFO "N_HDLC: init failure %d\n";
static int __init n_hdlc_init(void) static int __init n_hdlc_init(void)
{ {
int status; int status;
/* range check maxframe arg */ /* range check maxframe arg */
if ( maxframe<4096) if (maxframe < 4096)
maxframe=4096; maxframe = 4096;
else if ( maxframe>65535) else if (maxframe > 65535)
maxframe=65535; maxframe = 65535;
printk("HDLC line discipline: version %s, maxframe=%u\n", printk(hdlc_banner, maxframe);
szVersion, maxframe);
status = tty_register_ldisc(N_HDLC, &n_hdlc_ldisc); status = tty_register_ldisc(N_HDLC, &n_hdlc_ldisc);
if (!status) if (!status)
printk (KERN_INFO"N_HDLC line discipline registered.\n"); printk(hdlc_register_ok);
else else
printk (KERN_ERR"error registering line discipline: %d\n",status); printk(hdlc_register_fail, status);
if (status) if (status)
printk(KERN_INFO"N_HDLC: init failure %d\n", status); printk(hdlc_init_fail, status);
return (status); return status;
} /* end of init_module() */ } /* end of init_module() */
static char hdlc_unregister_ok[] __exitdata =
KERN_INFO "N_HDLC: line discipline unregistered\n";
static char hdlc_unregister_fail[] __exitdata =
KERN_ERR "N_HDLC: can't unregister line discipline (err = %d)\n";
static void __exit n_hdlc_exit(void) static void __exit n_hdlc_exit(void)
{ {
int status;
/* Release tty registration of line discipline */ /* Release tty registration of line discipline */
if ((status = tty_register_ldisc(N_HDLC, NULL))) int status = tty_register_ldisc(N_HDLC, NULL);
printk("N_HDLC: can't unregister line discipline (err = %d)\n", status);
if (status)
printk(hdlc_unregister_fail, status);
else else
printk("N_HDLC: line discipline unregistered\n"); printk(hdlc_unregister_ok);
} }
module_init(n_hdlc_init); module_init(n_hdlc_init);
module_exit(n_hdlc_exit); module_exit(n_hdlc_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Paul Fulghum paulkf@microgate.com");
MODULE_PARM(debuglevel, "i");
MODULE_PARM(maxframe, "i");
...@@ -300,17 +300,11 @@ static int nopnp; ...@@ -300,17 +300,11 @@ static int nopnp;
* *
* Both call el3_common_init/el3_common_remove. */ * Both call el3_common_init/el3_common_remove. */
static int __init el3_common_init (struct net_device *dev) static void __init el3_common_init(struct net_device *dev)
{ {
struct el3_private *lp = dev->priv; struct el3_private *lp = dev->priv;
short i; short i;
el3_cards++;
if (!lp->dev) /* probed devices are not chained */
{
lp->next_dev = el3_root_dev;
el3_root_dev = dev;
}
spin_lock_init(&lp->lock); spin_lock_init(&lp->lock);
if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */ if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */
...@@ -343,8 +337,6 @@ static int __init el3_common_init (struct net_device *dev) ...@@ -343,8 +337,6 @@ static int __init el3_common_init (struct net_device *dev)
dev->tx_timeout = el3_tx_timeout; dev->tx_timeout = el3_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
dev->do_ioctl = netdev_ioctl; dev->do_ioctl = netdev_ioctl;
return 0;
} }
static void el3_common_remove (struct net_device *dev) static void el3_common_remove (struct net_device *dev)
...@@ -374,6 +366,7 @@ static int __init el3_probe(int card_idx) ...@@ -374,6 +366,7 @@ static int __init el3_probe(int card_idx)
int ioaddr, irq, if_port; int ioaddr, irq, if_port;
u16 phys_addr[3]; u16 phys_addr[3];
static int current_tag; static int current_tag;
int err = -ENODEV;
#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) #if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
static int pnp_cards; static int pnp_cards;
struct pnp_dev *idev = NULL; struct pnp_dev *idev = NULL;
...@@ -413,7 +406,8 @@ static int __init el3_probe(int card_idx) ...@@ -413,7 +406,8 @@ static int __init el3_probe(int card_idx)
phys_addr[j] = phys_addr[j] =
htons(read_eeprom(ioaddr, j)); htons(read_eeprom(ioaddr, j));
if_port = read_eeprom(ioaddr, 8) >> 14; if_port = read_eeprom(ioaddr, 8) >> 14;
if (!(dev = init_etherdev(NULL, sizeof(struct el3_private)))) { dev = alloc_etherdev(sizeof (struct el3_private));
if (!dev) {
release_region(ioaddr, EL3_IO_EXTENT); release_region(ioaddr, EL3_IO_EXTENT);
pnp_device_detach(idev); pnp_device_detach(idev);
return -ENOMEM; return -ENOMEM;
...@@ -421,6 +415,8 @@ static int __init el3_probe(int card_idx) ...@@ -421,6 +415,8 @@ static int __init el3_probe(int card_idx)
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
pnp_cards++; pnp_cards++;
netdev_boot_setup_check(dev);
goto found; goto found;
} }
} }
...@@ -514,11 +510,14 @@ static int __init el3_probe(int card_idx) ...@@ -514,11 +510,14 @@ static int __init el3_probe(int card_idx)
irq = 13; irq = 13;
#endif #endif
if (!(dev = init_etherdev(NULL, sizeof(struct el3_private)))) dev = alloc_etherdev(sizeof (struct el3_private));
if (!dev)
return -ENOMEM; return -ENOMEM;
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
netdev_boot_setup_check(dev);
/* Set passed-in IRQ or I/O Addr. */ /* Set passed-in IRQ or I/O Addr. */
if (dev->irq > 1 && dev->irq < 16) if (dev->irq > 1 && dev->irq < 16)
irq = dev->irq; irq = dev->irq;
...@@ -527,15 +526,13 @@ static int __init el3_probe(int card_idx) ...@@ -527,15 +526,13 @@ static int __init el3_probe(int card_idx)
if (dev->mem_end == 0x3c509 /* Magic key */ if (dev->mem_end == 0x3c509 /* Magic key */
&& dev->base_addr >= 0x200 && dev->base_addr <= 0x3e0) && dev->base_addr >= 0x200 && dev->base_addr <= 0x3e0)
ioaddr = dev->base_addr & 0x3f0; ioaddr = dev->base_addr & 0x3f0;
else if (dev->base_addr != ioaddr) { else if (dev->base_addr != ioaddr)
unregister_netdev (dev); goto out;
return -ENODEV;
}
} }
if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509")) { if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509")) {
unregister_netdev (dev); err = -EBUSY;
return -EBUSY; goto out;
} }
/* Set the adaptor tag so that the next card can be found. */ /* Set the adaptor tag so that the next card can be found. */
...@@ -549,11 +546,8 @@ static int __init el3_probe(int card_idx) ...@@ -549,11 +546,8 @@ static int __init el3_probe(int card_idx)
#endif #endif
EL3WINDOW(0); EL3WINDOW(0);
if (inw(ioaddr) != 0x6d50) { if (inw(ioaddr) != 0x6d50)
unregister_netdev (dev); goto out1;
release_region(ioaddr, EL3_IO_EXTENT);
return -ENODEV;
}
/* Free the interrupt so that some other card can use it. */ /* Free the interrupt so that some other card can use it. */
outw(0x0f00, ioaddr + WN0_IRQ); outw(0x0f00, ioaddr + WN0_IRQ);
...@@ -570,6 +564,11 @@ static int __init el3_probe(int card_idx) ...@@ -570,6 +564,11 @@ static int __init el3_probe(int card_idx)
#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) #if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
lp->dev = &idev->dev; lp->dev = &idev->dev;
#endif #endif
el3_common_init(dev);
err = register_netdev(dev);
if (err)
goto out1;
#ifdef CONFIG_PM #ifdef CONFIG_PM
/* register power management */ /* register power management */
...@@ -581,7 +580,22 @@ static int __init el3_probe(int card_idx) ...@@ -581,7 +580,22 @@ static int __init el3_probe(int card_idx)
} }
#endif #endif
return el3_common_init (dev); el3_cards++;
#if !defined(__ISAPNP__) || defined(CONFIG_X86_PC9800)
lp->next_dev = el3_root_dev;
el3_root_dev = dev;
#endif
return 0;
out1:
release_region(ioaddr, EL3_IO_EXTENT);
#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
if (idev)
pnp_device_detach(idev);
#endif
out:
kfree(dev);
return err;
} }
#ifdef CONFIG_MCA #ifdef CONFIG_MCA
...@@ -602,6 +616,7 @@ static int __init el3_mca_probe(struct device *device) { ...@@ -602,6 +616,7 @@ static int __init el3_mca_probe(struct device *device) {
u_char pos4, pos5; u_char pos4, pos5;
struct mca_device *mdev = to_mca_device(device); struct mca_device *mdev = to_mca_device(device);
int slot = mdev->slot; int slot = mdev->slot;
int err;
pos4 = mca_device_read_stored_pos(mdev, 4); pos4 = mca_device_read_stored_pos(mdev, 4);
pos5 = mca_device_read_stored_pos(mdev, 5); pos5 = mca_device_read_stored_pos(mdev, 5);
...@@ -630,13 +645,14 @@ static int __init el3_mca_probe(struct device *device) { ...@@ -630,13 +645,14 @@ static int __init el3_mca_probe(struct device *device) {
phys_addr[i] = htons(read_eeprom(ioaddr, i)); phys_addr[i] = htons(read_eeprom(ioaddr, i));
} }
dev = init_etherdev(NULL, sizeof(struct el3_private)); dev = alloc_etherdev(sizeof (struct el3_private));
if (dev == NULL) { if (dev == NULL) {
release_region(ioaddr, EL3_IO_EXTENT); release_region(ioaddr, EL3_IO_EXTENT);
return -ENOMEM; return -ENOMEM;
} }
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
netdev_boot_setup_check(dev);
memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr)); memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
dev->base_addr = ioaddr; dev->base_addr = ioaddr;
...@@ -646,8 +662,16 @@ static int __init el3_mca_probe(struct device *device) { ...@@ -646,8 +662,16 @@ static int __init el3_mca_probe(struct device *device) {
lp->dev = device; lp->dev = device;
lp->type = EL3_MCA; lp->type = EL3_MCA;
device->driver_data = dev; device->driver_data = dev;
el3_common_init(dev);
err = register_netdev(dev);
if (err) {
release_region(ioaddr, EL3_IO_EXTENT);
return -ENOMEM;
}
return el3_common_init (dev); el3_cards++;
return 0;
} }
#endif /* CONFIG_MCA */ #endif /* CONFIG_MCA */
...@@ -661,6 +685,7 @@ static int __init el3_eisa_probe (struct device *device) ...@@ -661,6 +685,7 @@ static int __init el3_eisa_probe (struct device *device)
u16 phys_addr[3]; u16 phys_addr[3];
struct net_device *dev = NULL; struct net_device *dev = NULL;
struct eisa_device *edev; struct eisa_device *edev;
int err;
/* Yeepee, The driver framework is calling us ! */ /* Yeepee, The driver framework is calling us ! */
edev = to_eisa_device (device); edev = to_eisa_device (device);
...@@ -680,7 +705,7 @@ static int __init el3_eisa_probe (struct device *device) ...@@ -680,7 +705,7 @@ static int __init el3_eisa_probe (struct device *device)
/* Restore the "Product ID" to the EEPROM read register. */ /* Restore the "Product ID" to the EEPROM read register. */
read_eeprom(ioaddr, 3); read_eeprom(ioaddr, 3);
dev = init_etherdev(NULL, sizeof(struct el3_private)); dev = alloc_etherdev(sizeof (struct el3_private));
if (dev == NULL) { if (dev == NULL) {
release_region(ioaddr, EL3_IO_EXTENT); release_region(ioaddr, EL3_IO_EXTENT);
return -ENOMEM; return -ENOMEM;
...@@ -688,6 +713,8 @@ static int __init el3_eisa_probe (struct device *device) ...@@ -688,6 +713,8 @@ static int __init el3_eisa_probe (struct device *device)
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
netdev_boot_setup_check(dev);
memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr)); memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
dev->base_addr = ioaddr; dev->base_addr = ioaddr;
dev->irq = irq; dev->irq = irq;
...@@ -696,8 +723,16 @@ static int __init el3_eisa_probe (struct device *device) ...@@ -696,8 +723,16 @@ static int __init el3_eisa_probe (struct device *device)
lp->dev = device; lp->dev = device;
lp->type = EL3_EISA; lp->type = EL3_EISA;
eisa_set_drvdata (edev, dev); eisa_set_drvdata (edev, dev);
el3_common_init(dev);
return el3_common_init (dev); err = register_netdev(dev);
if (err) {
release_region(ioaddr, EL3_IO_EXTENT);
return err;
}
el3_cards++;
return 0;
} }
#endif #endif
......
...@@ -250,8 +250,6 @@ struct scc_info { ...@@ -250,8 +250,6 @@ struct scc_info {
/* Function declarations */ /* Function declarations */
int dmascc_init(void) __init;
static int setup_adapter(int card_base, int type, int n) __init; static int setup_adapter(int card_base, int type, int n) __init;
static void write_scc(struct scc_priv *priv, int reg, int val); static void write_scc(struct scc_priv *priv, int reg, int val);
...@@ -299,23 +297,12 @@ static struct scc_info *first; ...@@ -299,23 +297,12 @@ static struct scc_info *first;
static unsigned long rand; static unsigned long rand;
/* Module functions */
#ifdef MODULE
MODULE_AUTHOR("Klaus Kudielka"); MODULE_AUTHOR("Klaus Kudielka");
MODULE_DESCRIPTION("Driver for high-speed SCC boards"); MODULE_DESCRIPTION("Driver for high-speed SCC boards");
MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NUM_DEVS) "i"); MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NUM_DEVS) "i");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static void __exit dmascc_exit(void) {
int init_module(void) {
return dmascc_init();
}
void cleanup_module(void) {
int i; int i;
struct scc_info *info; struct scc_info *info;
...@@ -341,24 +328,16 @@ void cleanup_module(void) { ...@@ -341,24 +328,16 @@ void cleanup_module(void) {
} }
} }
#ifndef MODULE
#else
void __init dmascc_setup(char *str, int *ints) { void __init dmascc_setup(char *str, int *ints) {
int i; int i;
for (i = 0; i < MAX_NUM_DEVS && i < ints[0]; i++) for (i = 0; i < MAX_NUM_DEVS && i < ints[0]; i++)
io[i] = ints[i+1]; io[i] = ints[i+1];
} }
#endif #endif
static int __init dmascc_init(void) {
/* Initialization functions */
int __init dmascc_init(void) {
int h, i, j, n; int h, i, j, n;
int base[MAX_NUM_DEVS], tcmd[MAX_NUM_DEVS], t0[MAX_NUM_DEVS], int base[MAX_NUM_DEVS], tcmd[MAX_NUM_DEVS], t0[MAX_NUM_DEVS],
t1[MAX_NUM_DEVS]; t1[MAX_NUM_DEVS];
...@@ -461,6 +440,9 @@ int __init dmascc_init(void) { ...@@ -461,6 +440,9 @@ int __init dmascc_init(void) {
return -EIO; return -EIO;
} }
module_init(dmascc_init);
module_exit(dmascc_exit);
int __init setup_adapter(int card_base, int type, int n) { int __init setup_adapter(int card_base, int type, int n) {
int i, irq, chip; int i, irq, chip;
...@@ -580,6 +562,7 @@ int __init setup_adapter(int card_base, int type, int n) { ...@@ -580,6 +562,7 @@ int __init setup_adapter(int card_base, int type, int n) {
if (sizeof(dev->name) == sizeof(char *)) dev->name = priv->name; if (sizeof(dev->name) == sizeof(char *)) dev->name = priv->name;
#endif #endif
sprintf(dev->name, "dmascc%i", 2*n+i); sprintf(dev->name, "dmascc%i", 2*n+i);
SET_MODULE_OWNER(dev);
dev->base_addr = card_base; dev->base_addr = card_base;
dev->irq = irq; dev->irq = irq;
dev->open = scc_open; dev->open = scc_open;
...@@ -707,12 +690,9 @@ static int scc_open(struct net_device *dev) { ...@@ -707,12 +690,9 @@ static int scc_open(struct net_device *dev) {
struct scc_info *info = priv->info; struct scc_info *info = priv->info;
int card_base = priv->card_base; int card_base = priv->card_base;
MOD_INC_USE_COUNT;
/* Request IRQ if not already used by other channel */ /* Request IRQ if not already used by other channel */
if (!info->irq_used) { if (!info->irq_used) {
if (request_irq(dev->irq, scc_isr, 0, "dmascc", info)) { if (request_irq(dev->irq, scc_isr, 0, "dmascc", info)) {
MOD_DEC_USE_COUNT;
return -EAGAIN; return -EAGAIN;
} }
} }
...@@ -722,7 +702,6 @@ static int scc_open(struct net_device *dev) { ...@@ -722,7 +702,6 @@ static int scc_open(struct net_device *dev) {
if (priv->param.dma >= 0) { if (priv->param.dma >= 0) {
if (request_dma(priv->param.dma, "dmascc")) { if (request_dma(priv->param.dma, "dmascc")) {
if (--info->irq_used == 0) free_irq(dev->irq, info); if (--info->irq_used == 0) free_irq(dev->irq, info);
MOD_DEC_USE_COUNT;
return -EAGAIN; return -EAGAIN;
} else { } else {
unsigned long flags = claim_dma_lock(); unsigned long flags = claim_dma_lock();
...@@ -866,7 +845,6 @@ static int scc_close(struct net_device *dev) { ...@@ -866,7 +845,6 @@ static int scc_close(struct net_device *dev) {
} }
if (--info->irq_used == 0) free_irq(dev->irq, info); if (--info->irq_used == 0) free_irq(dev->irq, info);
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
......
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/netlink.h> #include <linux/netlink.h>
extern int dmascc_init(void);
extern int scc_enet_init(void); extern int scc_enet_init(void);
extern int fec_enet_init(void); extern int fec_enet_init(void);
...@@ -29,10 +27,6 @@ static struct net_probe pci_probes[] __initdata = { ...@@ -29,10 +27,6 @@ static struct net_probe pci_probes[] __initdata = {
/* /*
* Early setup devices * Early setup devices
*/ */
#if defined(CONFIG_DMASCC)
{dmascc_init, 0},
#endif
#if defined(CONFIG_SCC_ENET) #if defined(CONFIG_SCC_ENET)
{scc_enet_init, 0}, {scc_enet_init, 0},
#endif #endif
......
...@@ -383,6 +383,7 @@ struct s_DevNet { ...@@ -383,6 +383,7 @@ struct s_DevNet {
int Mtu; int Mtu;
int Up; int Up;
SK_AC *pAC; SK_AC *pAC;
struct proc_dir_entry *proc;
}; };
typedef struct s_TxPort TX_PORT; typedef struct s_TxPort TX_PORT;
......
...@@ -351,11 +351,7 @@ static int SkGeIocMib(DEV_NET*, unsigned int, int); ...@@ -351,11 +351,7 @@ static int SkGeIocMib(DEV_NET*, unsigned int, int);
static const char SK_Root_Dir_entry[] = "sk98lin"; static const char SK_Root_Dir_entry[] = "sk98lin";
static struct proc_dir_entry *pSkRootDir; static struct proc_dir_entry *pSkRootDir;
extern struct file_operations sk_proc_fops;
//extern struct proc_dir_entry Our_Proc_Dir;
extern int sk_proc_read(char *buffer, char **buffer_location,
off_t offset, int buffer_length, int *eof, void *data);
#ifdef DEBUG #ifdef DEBUG
static void DumpMsg(struct sk_buff*, char*); static void DumpMsg(struct sk_buff*, char*);
...@@ -399,7 +395,6 @@ static int __init skge_probe (void) ...@@ -399,7 +395,6 @@ static int __init skge_probe (void)
struct pci_dev *pdev = NULL; struct pci_dev *pdev = NULL;
unsigned long base_address; unsigned long base_address;
struct net_device *dev = NULL; struct net_device *dev = NULL;
struct proc_dir_entry *pProcFile;
if (probed) if (probed)
return -ENODEV; return -ENODEV;
...@@ -420,7 +415,6 @@ static int __init skge_probe (void) ...@@ -420,7 +415,6 @@ static int __init skge_probe (void)
while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT, while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT,
PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) { PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) {
dev = NULL;
pNet = NULL; pNet = NULL;
if (pci_enable_device(pdev)) if (pci_enable_device(pdev))
...@@ -431,7 +425,8 @@ static int __init skge_probe (void) ...@@ -431,7 +425,8 @@ static int __init skge_probe (void)
pci_set_dma_mask(pdev, (u64) 0xffffffff)) pci_set_dma_mask(pdev, (u64) 0xffffffff))
continue; continue;
if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == 0) { dev = alloc_etherdev(sizeof(DEV_NET));
if (!dev) {
printk(KERN_ERR "Unable to allocate etherdev " printk(KERN_ERR "Unable to allocate etherdev "
"structure!\n"); "structure!\n");
break; break;
...@@ -440,7 +435,7 @@ static int __init skge_probe (void) ...@@ -440,7 +435,7 @@ static int __init skge_probe (void)
pNet = dev->priv; pNet = dev->priv;
pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
if (pNet->pAC == NULL){ if (pNet->pAC == NULL){
kfree(dev->priv); kfree(dev);
printk(KERN_ERR "Unable to allocate adapter " printk(KERN_ERR "Unable to allocate adapter "
"structure!\n"); "structure!\n");
break; break;
...@@ -477,15 +472,6 @@ static int __init skge_probe (void) ...@@ -477,15 +472,6 @@ static int __init skge_probe (void)
proc_root_initialized = 1; proc_root_initialized = 1;
} }
pProcFile = create_proc_entry(dev->name,
S_IFREG | 0444, pSkRootDir);
pProcFile->read_proc = sk_proc_read;
pProcFile->write_proc = NULL;
pProcFile->nlink = 1;
pProcFile->size = sizeof(dev->name+1);
pProcFile->data = (void*)pProcFile;
pProcFile->owner = THIS_MODULE;
/* /*
* Dummy value. * Dummy value.
*/ */
...@@ -532,11 +518,29 @@ static int __init skge_probe (void) ...@@ -532,11 +518,29 @@ static int __init skge_probe (void)
pNet->PortNr = 0; pNet->PortNr = 0;
pNet->NetNr = 0; pNet->NetNr = 0;
if (register_netdev(dev) != 0) {
printk(KERN_ERR "Unable to register etherdev\n");
sk98lin_root_dev = pAC->Next;
remove_proc_entry(dev->name, pSkRootDir);
FreeResources(dev);
kfree(dev);
continue;
}
pNet->proc = create_proc_entry(dev->name,
S_IFREG | 0444, pSkRootDir);
if (pNet->proc) {
pNet->proc->data = dev;
pNet->proc->owner = THIS_MODULE;
pNet->proc->proc_fops = &sk_proc_fops;
}
boards_found++; boards_found++;
/* More then one port found */ /* More then one port found */
if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
if ((dev = init_etherdev(NULL, sizeof(DEV_NET))) == 0) { dev = alloc_etherdev(sizeof(DEV_NET));
if (!dev) {
printk(KERN_ERR "Unable to allocate etherdev " printk(KERN_ERR "Unable to allocate etherdev "
"structure!\n"); "structure!\n");
break; break;
...@@ -559,21 +563,26 @@ static int __init skge_probe (void) ...@@ -559,21 +563,26 @@ static int __init skge_probe (void)
dev->do_ioctl = &SkGeIoctl; dev->do_ioctl = &SkGeIoctl;
dev->change_mtu = &SkGeChangeMtu; dev->change_mtu = &SkGeChangeMtu;
pProcFile = create_proc_entry(dev->name,
S_IFREG | 0444, pSkRootDir);
pProcFile->read_proc = sk_proc_read;
pProcFile->write_proc = NULL;
pProcFile->nlink = 1;
pProcFile->size = sizeof(dev->name+1);
pProcFile->data = (void*)pProcFile;
pProcFile->owner = THIS_MODULE;
memcpy((caddr_t) &dev->dev_addr, memcpy((caddr_t) &dev->dev_addr,
(caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6); (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
printk("%s: %s\n", dev->name, pAC->DeviceStr); printk("%s: %s\n", dev->name, pAC->DeviceStr);
printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
if (register_netdev(dev) != 0) {
printk(KERN_ERR "Unable to register etherdev\n");
kfree(dev);
break;
}
pNet->proc = create_proc_entry(dev->name,
S_IFREG | 0444, pSkRootDir);
if (pNet->proc) {
pNet->proc->data = dev;
pNet->proc->owner = THIS_MODULE;
pNet->proc->proc_fops = &sk_proc_fops;
}
} }
...@@ -740,6 +749,7 @@ static int __init skge_init_module(void) ...@@ -740,6 +749,7 @@ static int __init skge_init_module(void)
return cards ? 0 : -ENODEV; return cards ? 0 : -ENODEV;
} /* skge_init_module */ } /* skge_init_module */
spinlock_t sk_devs_lock = SPIN_LOCK_UNLOCKED;
/***************************************************************************** /*****************************************************************************
* *
...@@ -766,6 +776,11 @@ SK_EVPARA EvPara; ...@@ -766,6 +776,11 @@ SK_EVPARA EvPara;
netif_stop_queue(sk98lin_root_dev); netif_stop_queue(sk98lin_root_dev);
SkGeYellowLED(pAC, pAC->IoBase, 0); SkGeYellowLED(pAC, pAC->IoBase, 0);
if (pNet->proc) {
spin_lock(&sk_devs_lock);
pNet->proc->data = NULL;
spin_unlock(&sk_devs_lock);
}
if(pAC->BoardLevel == 2) { if(pAC->BoardLevel == 2) {
/* board is still alive */ /* board is still alive */
...@@ -792,6 +807,12 @@ SK_EVPARA EvPara; ...@@ -792,6 +807,12 @@ SK_EVPARA EvPara;
} }
if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){ if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
pNet = (DEV_NET*) pAC->dev[1]->priv;
if (pNet->proc) {
spin_lock(&sk_devs_lock);
pNet->proc->data = NULL;
spin_unlock(&sk_devs_lock);
}
unregister_netdev(pAC->dev[1]); unregister_netdev(pAC->dev[1]);
kfree(pAC->dev[1]); kfree(pAC->dev[1]);
} }
......
...@@ -46,378 +46,168 @@ ...@@ -46,378 +46,168 @@
#include "h/skdrv1st.h" #include "h/skdrv1st.h"
#include "h/skdrv2nd.h" #include "h/skdrv2nd.h"
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
//#define SPECIAL 32 /* 0x */
#define LARGE 64
extern char * SkNumber(char * str, long long num, int base, int size, extern spinlock_t sk_devs_lock;
int precision ,int type);
int proc_read(char *buffer,
char **buffer_location,
off_t offset,
int buffer_length,
int *eof,
void *data);
static int sk_show_dev(struct net_device *dev, char *buf)
extern struct net_device *sk98lin_root_dev;
/*****************************************************************************
*
* proc_read - print "summaries" entry
*
* Description:
* This function fills the proc entry with statistic data about
* the ethernet device.
*
*
* Returns: buffer with statistic data
*
*/
int sk_proc_read(char *buffer,
char **buffer_location,
off_t offset,
int buffer_length,
int *eof,
void *data)
{ {
DEV_NET *pNet = (DEV_NET*) dev->priv;
SK_AC *pAC = pNet->pAC;
int t = pNet->PortNr;
SK_RLMT_NET *rlmt = &pAC->Rlmt.Net[t];
unsigned long Flags;
unsigned Size;
int len = 0; int len = 0;
int t;
int i; int i;
DEV_NET *pNet;
SK_AC *pAC;
char test_buf[100];
unsigned long Flags;
unsigned int Size;
struct net_device *next;
struct net_device *SkgeProcDev = sk98lin_root_dev;
SK_PNMI_STRUCT_DATA *pPnmiStruct; SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
SK_PNMI_STAT *pPnmiStat; SK_PNMI_STAT *pPnmiStat;
struct proc_dir_entry *file = (struct proc_dir_entry*) data;
while (SkgeProcDev) {
pNet = (DEV_NET*) SkgeProcDev->priv;
pAC = pNet->pAC;
next = pAC->Next;
pPnmiStruct = &pAC->PnmiStruct;
/* NetIndex in GetStruct is now required, zero is only dummy */
for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
t--;
spin_lock_irqsave(&pAC->SlowPathLock, Flags); spin_lock_irqsave(&pAC->SlowPathLock, Flags);
Size = SK_PNMI_STRUCT_SIZE; Size = SK_PNMI_STRUCT_SIZE;
SkPnmiGetStruct(pAC, pAC->IoBase, SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t);
pPnmiStruct, &Size, t-1);
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
if (strcmp(pAC->dev[t-1]->name, file->name) == 0) {
pPnmiStat = &pPnmiStruct->Stat[0]; pPnmiStat = &pPnmiStruct->Stat[0];
len = sprintf(buffer,
"\nDetailed statistic for device %s\n", len = sprintf(buf, "\nDetailed statistic for device %s\n", dev->name);
pAC->dev[t-1]->name); len += sprintf(buf + len, "==================================\n");
len += sprintf(buffer + len,
"==================================\n");
/* Board statistics */ /* Board statistics */
len += sprintf(buffer + len, len += sprintf(buf + len, "\nBoard statistics\n\n");
"\nBoard statistics\n\n"); len += sprintf(buf + len, "Active Port %c\n",
len += sprintf(buffer + len, 'A' + rlmt->Port[rlmt->ActivePort]->PortNumber);
"Active Port %c\n", len += sprintf(buf + len, "Preferred Port %c\n",
'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt. 'A' + rlmt->Port[rlmt->PrefPort]->PortNumber);
Net[t-1].PrefPort]->PortNumber);
len += sprintf(buffer + len,
"Preferred Port %c\n",
'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
Net[t-1].PrefPort]->PortNumber);
len += sprintf(buffer + len, len += sprintf(buf + len, "Bus speed (Mhz) %d\n",
"Bus speed (Mhz) %d\n",
pPnmiStruct->BusSpeed); pPnmiStruct->BusSpeed);
len += sprintf(buffer + len, len += sprintf(buf + len, "Bus width (Bit) %d\n",
"Bus width (Bit) %d\n",
pPnmiStruct->BusWidth); pPnmiStruct->BusWidth);
for (i=0; i < SK_MAX_SENSORS; i ++) { for (i=0; i < SK_MAX_SENSORS; i ++) {
if (strcmp(pAC->I2c.SenTable[i].SenDesc, SK_SENSOR *sens = &pAC->I2c.SenTable[i];
"Temperature") == 0 ) { SK_I32 val = sens->SenValue;
len += sprintf(buffer + len, if (strcmp(sens->SenDesc, "Temperature") == 0 ) {
len += sprintf(buf + len,
"Temperature (C) %d.%d\n", "Temperature (C) %d.%d\n",
pAC->I2c.SenTable[i].SenValue / 10, val / 10, val % 10);
pAC->I2c.SenTable[i].SenValue % 10); val = val * 18 + 3200;
len += sprintf(buffer + len, len += sprintf(buf + len,
"Temperature (F) %d.%d\n", "Temperature (F) %d.%d\n",
((((pAC->I2c.SenTable[i].SenValue) val/100, val % 10);
*10)*9)/5 + 3200)/100, } else if (strcmp(sens->SenDesc, "Speed Fan") == 0 ) {
((((pAC->I2c.SenTable[i].SenValue) len += sprintf(buf + len,
*10)*9)/5 + 3200) % 10);
} else if (strcmp(pAC->I2c.SenTable[i].SenDesc,
"Speed Fan") == 0 ) {
len += sprintf(buffer + len,
"Speed Fan %d\n", "Speed Fan %d\n",
pAC->I2c.SenTable[i].SenValue); val);
} else { } else {
len += sprintf(buffer + len, len += sprintf(buf + len,
"%-20s %d.%d\n", "%-20s %d.%d\n",
pAC->I2c.SenTable[i].SenDesc, sens->SenDesc, val / 1000, val % 1000);
pAC->I2c.SenTable[i].SenValue / 1000,
pAC->I2c.SenTable[i].SenValue % 1000);
} }
} }
/*Receive statistics */ /*Receive statistics */
len += sprintf(buffer + len, len += sprintf(buf + len, "\nReceive statistics\n\n");
"\nReceive statistics\n\n");
len += sprintf(buf + len, "Received bytes %Ld\n",
len += sprintf(buffer + len, (unsigned long long) pPnmiStat->StatRxOctetsOkCts);
"Received bytes %s\n", len += sprintf(buf + len, "Received packets %Ld\n",
SkNumber(test_buf, pPnmiStat->StatRxOctetsOkCts, (unsigned long long) pPnmiStat->StatRxOkCts);
10,0,-1,0)); len += sprintf(buf + len, "Received errors %Ld\n",
len += sprintf(buffer + len, (unsigned long long) pPnmiStat->StatRxFcsCts);
"Received packets %s\n", len += sprintf(buf + len, "Received dropped %Ld\n",
SkNumber(test_buf, pPnmiStat->StatRxOkCts, (unsigned long long) pPnmiStruct->RxNoBufCts);
10,0,-1,0)); len += sprintf(buf + len, "Received multicast %Ld\n",
len += sprintf(buffer + len, (unsigned long long) pPnmiStat->StatRxMulticastOkCts);
"Received errors %s\n", len += sprintf(buf + len, "Received errors types\n");
SkNumber(test_buf, pPnmiStat->StatRxFcsCts, len += sprintf(buf + len, " length errors %Ld\n",
10,0,-1,0)); (unsigned long long) pPnmiStat->StatRxRuntCts);
len += sprintf(buffer + len, len += sprintf(buf + len, " over errors %Ld\n",
"Received dropped %s\n", (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
SkNumber(test_buf, pPnmiStruct->RxNoBufCts, len += sprintf(buf + len, " crc errors %Ld\n",
10,0,-1,0)); (unsigned long long) pPnmiStat->StatRxFcsCts);
len += sprintf(buffer + len, len += sprintf(buf + len, " frame errors %Ld\n",
"Received multicast %s\n", (unsigned long long) pPnmiStat->StatRxFramingCts);
SkNumber(test_buf, pPnmiStat->StatRxMulticastOkCts, len += sprintf(buf + len, " fifo errors %Ld\n",
10,0,-1,0)); (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
len += sprintf(buffer + len, len += sprintf(buf + len, " missed errors %Ld\n",
"Received errors types\n"); (unsigned long long) pPnmiStat->StatRxMissedCts);
len += sprintf(buffer + len,
" length errors %s\n",
SkNumber(test_buf, pPnmiStat->StatRxRuntCts,
10, 0, -1, 0));
len += sprintf(buffer + len,
" over errors %s\n",
SkNumber(test_buf, pPnmiStat->StatRxFifoOverflowCts,
10, 0, -1, 0));
len += sprintf(buffer + len,
" crc errors %s\n",
SkNumber(test_buf, pPnmiStat->StatRxFcsCts,
10, 0, -1, 0));
len += sprintf(buffer + len,
" frame errors %s\n",
SkNumber(test_buf, pPnmiStat->StatRxFramingCts,
10, 0, -1, 0));
len += sprintf(buffer + len,
" fifo errors %s\n",
SkNumber(test_buf, pPnmiStat->StatRxFifoOverflowCts,
10, 0, -1, 0));
len += sprintf(buffer + len,
" missed errors %s\n",
SkNumber(test_buf, pPnmiStat->StatRxMissedCts,
10, 0, -1, 0));
/*Transmit statistics */ /*Transmit statistics */
len += sprintf(buffer + len, len += sprintf(buf + len, "\nTransmit statistics\n\n");
"\nTransmit statistics\n\n");
len += sprintf(buf + len, "Transmit bytes %Ld\n",
len += sprintf(buffer + len, (unsigned long long) pPnmiStat->StatTxOctetsOkCts);
"Transmit bytes %s\n", len += sprintf(buf + len, "Transmit packets %Ld\n",
SkNumber(test_buf, pPnmiStat->StatTxOctetsOkCts, (unsigned long long) pPnmiStat->StatTxOkCts);
10,0,-1,0)); len += sprintf(buf + len, "Transmit errors %Ld\n",
len += sprintf(buffer + len, (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
"Transmit packets %s\n", len += sprintf(buf + len, "Transmit dropped %Ld\n",
SkNumber(test_buf, pPnmiStat->StatTxOkCts, (unsigned long long) pPnmiStruct->TxNoBufCts);
10,0,-1,0)); len += sprintf(buf + len, "Transmit collisions %Ld\n",
len += sprintf(buffer + len, (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
"Transmit errors %s\n", len += sprintf(buf + len, "Transmited errors types\n");
SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts, len += sprintf(buf + len, " aborted errors %ld\n",
10,0,-1,0));
len += sprintf(buffer + len,
"Transmit dropped %s\n",
SkNumber(test_buf, pPnmiStruct->TxNoBufCts,
10,0,-1,0));
len += sprintf(buffer + len,
"Transmit collisions %s\n",
SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts,
10,0,-1,0));
len += sprintf(buffer + len,
"Transmited errors types\n");
len += sprintf(buffer + len,
" aborted errors %ld\n",
pAC->stats.tx_aborted_errors); pAC->stats.tx_aborted_errors);
len += sprintf(buffer + len, len += sprintf(buf + len, " carrier errors %Ld\n",
" carrier errors %s\n", (unsigned long long) pPnmiStat->StatTxCarrierCts);
SkNumber(test_buf, pPnmiStat->StatTxCarrierCts, len += sprintf(buf + len, " fifo errors %Ld\n",
10, 0, -1, 0)); (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
len += sprintf(buffer + len, len += sprintf(buf + len, " heartbeat errors %Ld\n",
" fifo errors %s\n", (unsigned long long) pPnmiStat->StatTxCarrierCts);
SkNumber(test_buf, pPnmiStat->StatTxFifoUnderrunCts, len += sprintf(buf + len, " window errors %ld\n",
10, 0, -1, 0));
len += sprintf(buffer + len,
" heartbeat errors %s\n",
SkNumber(test_buf, pPnmiStat->StatTxCarrierCts,
10, 0, -1, 0));
len += sprintf(buffer + len,
" window errors %ld\n",
pAC->stats.tx_window_errors); pAC->stats.tx_window_errors);
} return len;
}
SkgeProcDev = next;
}
if (offset >= len) {
*eof = 1;
return 0;
}
*buffer_location = buffer + offset;
if (buffer_length >= len - offset) {
*eof = 1;
}
return (min_t(int, buffer_length, len - offset));
} }
static ssize_t sk_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
/*****************************************************************************
*
* SkDoDiv - convert 64bit number
*
* Description:
* This function "converts" a long long number.
*
* Returns:
* remainder of division
*/
static long SkDoDiv (long long Dividend, int Divisor, long long *pErg)
{ {
long Rest; struct inode * inode = file->f_dentry->d_inode;
long long Ergebnis; struct proc_dir_entry *entry = PDE(inode);
long Akku; char *page = (char *)__get_free_page(GFP_KERNEL);
struct net_device *dev;
loff_t pos = *ppos;
Akku = Dividend >> 32; ssize_t res = 0;
int len = 0;
Ergebnis = ((long long) (Akku / Divisor)) << 32;
Rest = Akku % Divisor ;
Akku = Rest << 16;
Akku |= ((Dividend & 0xFFFF0000) >> 16);
Ergebnis += ((long long) (Akku / Divisor)) << 16;
Rest = Akku % Divisor ;
Akku = Rest << 16;
Akku |= (Dividend & 0xFFFF);
Ergebnis += (Akku / Divisor);
Rest = Akku % Divisor ;
*pErg = Ergebnis; if (!page)
return (Rest); return -ENOMEM;
spin_lock(&sk_devs_lock);
dev = entry->data;
if (dev)
len = sk_show_dev(dev, page);
spin_unlock(&sk_devs_lock);
if (pos >= 0 && pos < len) {
res = nbytes;
if (res > len - pos)
res = len - pos;
if (copy_to_user(page + pos, buf, nbytes))
res = -EFAULT;
else
*ppos = pos + res;
}
free_page((unsigned long) page);
return nbytes;
} }
static loff_t sk_lseek(struct file *file, loff_t offset, int orig)
#if 0
#define do_div(n,base) ({ \
long long __res; \
__res = ((unsigned long long) n) % (unsigned) base; \
n = ((unsigned long long) n) / (unsigned) base; \
__res; })
#endif
/*****************************************************************************
*
* SkNumber - Print results
*
* Description:
* This function converts a long long number into a string.
*
* Returns:
* number as string
*/
char * SkNumber(char * str, long long num, int base, int size, int precision
,int type)
{ {
char c,sign,tmp[66], *strorg = str; switch (orig) {
const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; case 1:
int i; offset += file->f_pos;
case 0:
if (type & LARGE) if (offset >= 0)
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; return file->f_pos = offset;
if (type & LEFT)
type &= ~ZEROPAD;
if (base < 2 || base > 36)
return 0;
c = (type & ZEROPAD) ? '0' : ' ';
sign = 0;
if (type & SIGN) {
if (num < 0) {
sign = '-';
num = -num;
size--;
} else if (type & PLUS) {
sign = '+';
size--;
} else if (type & SPACE) {
sign = ' ';
size--;
} }
} return -EINVAL;
if (type & SPECIAL) {
if (base == 16)
size -= 2;
else if (base == 8)
size--;
}
i = 0;
if (num == 0)
tmp[i++]='0';
else while (num != 0)
tmp[i++] = digits[SkDoDiv(num,base, &num)];
if (i > precision)
precision = i;
size -= precision;
if (!(type&(ZEROPAD+LEFT)))
while(size-->0)
*str++ = ' ';
if (sign)
*str++ = sign;
if (type & SPECIAL) {
if (base==8)
*str++ = '0';
else if (base==16) {
*str++ = '0';
*str++ = digits[33];
}
}
if (!(type & LEFT))
while (size-- > 0)
*str++ = c;
while (i < precision--)
*str++ = '0';
while (i-- > 0)
*str++ = tmp[i];
while (size-- > 0)
*str++ = ' ';
str[0] = '\0';
return strorg;
} }
struct file_operations sk_proc_fops = {
.read = sk_read,
.llseek = sk_lseek,
};
...@@ -1682,11 +1682,13 @@ static int __init init_sdla(void) ...@@ -1682,11 +1682,13 @@ static int __init init_sdla(void)
static void __exit exit_sdla(void) static void __exit exit_sdla(void)
{ {
#ifdef MODULE
unregister_netdev(&sdla0); unregister_netdev(&sdla0);
if (sdla0.priv) if (sdla0.priv)
kfree(sdla0.priv); kfree(sdla0.priv);
if (sdla0.irq) if (sdla0.irq)
free_irq(sdla0.irq, &sdla0); free_irq(sdla0.irq, &sdla0);
#endif
} }
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
#define RTM_MAX (RTM_BASE+31) #define RTM_MAX (RTM_BASE+31)
/* /*
Generic structure for encapsulation optional route information. Generic structure for encapsulation of optional route information.
It is reminiscent of sockaddr, but with sa_family replaced It is reminiscent of sockaddr, but with sa_family replaced
with attribute type. with attribute type.
*/ */
......
...@@ -111,9 +111,10 @@ static inline void fib6_walker_unlink(struct fib6_walker_t *w) ...@@ -111,9 +111,10 @@ static inline void fib6_walker_unlink(struct fib6_walker_t *w)
struct rt6_statistics { struct rt6_statistics {
__u32 fib_nodes; __u32 fib_nodes;
__u32 fib_route_nodes; __u32 fib_route_nodes;
__u32 fib_rt_alloc; /* permanet routes */ __u32 fib_rt_alloc; /* permanent routes */
__u32 fib_rt_entries; /* rt entries in table */ __u32 fib_rt_entries; /* rt entries in table */
__u32 fib_rt_cache; /* cache routes */ __u32 fib_rt_cache; /* cache routes */
__u32 fib_discarded_routes;
}; };
#define RTN_TL_ROOT 0x0001 #define RTN_TL_ROOT 0x0001
......
...@@ -42,6 +42,11 @@ ...@@ -42,6 +42,11 @@
*/ */
/*
* RFC 1213: MIB-II
* RFC 2011 (updates 1213): SNMPv2-MIB-IP
* RFC 2863: Interfaces Group MIB
*/
struct ip_mib struct ip_mib
{ {
unsigned long IpInReceives; unsigned long IpInReceives;
...@@ -64,6 +69,9 @@ struct ip_mib ...@@ -64,6 +69,9 @@ struct ip_mib
unsigned long __pad[0]; unsigned long __pad[0];
}; };
/*
* RFC 2465: IPv6 MIB: General Group
*/
struct ipv6_mib struct ipv6_mib
{ {
unsigned long Ip6InReceives; unsigned long Ip6InReceives;
...@@ -91,6 +99,10 @@ struct ipv6_mib ...@@ -91,6 +99,10 @@ struct ipv6_mib
unsigned long __pad[0]; unsigned long __pad[0];
}; };
/*
* RFC 1213: MIB-II ICMP Group
* RFC 2011 (updates 1213): SNMPv2 MIB for IP: ICMP group
*/
struct icmp_mib struct icmp_mib
{ {
unsigned long IcmpInMsgs; unsigned long IcmpInMsgs;
...@@ -123,6 +135,9 @@ struct icmp_mib ...@@ -123,6 +135,9 @@ struct icmp_mib
unsigned long __pad[0]; unsigned long __pad[0];
}; };
/*
* RFC 2466: ICMPv6-MIB
*/
struct icmpv6_mib struct icmpv6_mib
{ {
unsigned long Icmp6InMsgs; unsigned long Icmp6InMsgs;
...@@ -161,6 +176,10 @@ struct icmpv6_mib ...@@ -161,6 +176,10 @@ struct icmpv6_mib
unsigned long __pad[0]; unsigned long __pad[0];
}; };
/*
* RFC 1213: MIB-II TCP group
* RFC 2012 (updates 1213): SNMPv2-MIB-TCP
*/
struct tcp_mib struct tcp_mib
{ {
unsigned long TcpRtoAlgorithm; unsigned long TcpRtoAlgorithm;
...@@ -180,6 +199,10 @@ struct tcp_mib ...@@ -180,6 +199,10 @@ struct tcp_mib
unsigned long __pad[0]; unsigned long __pad[0];
}; };
/*
* RFC 1213: MIB-II UDP group
* RFC 2013 (updates 1213): SNMPv2-MIB-UDP
*/
struct udp_mib struct udp_mib
{ {
unsigned long UdpInDatagrams; unsigned long UdpInDatagrams;
......
/* /*
* net/dst.c Protocol independent destination cache. * net/core/dst.c Protocol independent destination cache.
* *
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
* *
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
* *
* Generic frame diversion * Generic frame diversion
* *
* Version: @(#)eth.c 0.41 09/09/2000
*
* Authors: * Authors:
* Benoit LOCHER: initial integration within the kernel with support for ethernet * Benoit LOCHER: initial integration within the kernel with support for ethernet
* Dave Miller: improvement on the code (correctness, performance and source files) * Dave Miller: improvement on the code (correctness, performance and source files)
......
...@@ -36,14 +36,13 @@ ...@@ -36,14 +36,13 @@
#include <linux/filter.h> #include <linux/filter.h>
/* No hurry in this branch */ /* No hurry in this branch */
static u8 *load_pointer(struct sk_buff *skb, int k) static u8 *load_pointer(struct sk_buff *skb, int k)
{ {
u8 *ptr = NULL; u8 *ptr = NULL;
if (k>=SKF_NET_OFF) if (k >= SKF_NET_OFF)
ptr = skb->nh.raw + k - SKF_NET_OFF; ptr = skb->nh.raw + k - SKF_NET_OFF;
else if (k>=SKF_LL_OFF) else if (k >= SKF_LL_OFF)
ptr = skb->mac.raw + k - SKF_LL_OFF; ptr = skb->mac.raw + k - SKF_LL_OFF;
if (ptr >= skb->head && ptr < skb->tail) if (ptr >= skb->head && ptr < skb->tail)
...@@ -80,134 +79,106 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) ...@@ -80,134 +79,106 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
/* /*
* Process array of filter instructions. * Process array of filter instructions.
*/ */
for (pc = 0; pc < flen; pc++) {
for(pc = 0; pc < flen; pc++)
{
fentry = &filter[pc]; fentry = &filter[pc];
switch(fentry->code) switch (fentry->code) {
{
case BPF_ALU|BPF_ADD|BPF_X: case BPF_ALU|BPF_ADD|BPF_X:
A += X; A += X;
continue; continue;
case BPF_ALU|BPF_ADD|BPF_K: case BPF_ALU|BPF_ADD|BPF_K:
A += fentry->k; A += fentry->k;
continue; continue;
case BPF_ALU|BPF_SUB|BPF_X: case BPF_ALU|BPF_SUB|BPF_X:
A -= X; A -= X;
continue; continue;
case BPF_ALU|BPF_SUB|BPF_K: case BPF_ALU|BPF_SUB|BPF_K:
A -= fentry->k; A -= fentry->k;
continue; continue;
case BPF_ALU|BPF_MUL|BPF_X: case BPF_ALU|BPF_MUL|BPF_X:
A *= X; A *= X;
continue; continue;
case BPF_ALU|BPF_MUL|BPF_K: case BPF_ALU|BPF_MUL|BPF_K:
A *= fentry->k; A *= fentry->k;
continue; continue;
case BPF_ALU|BPF_DIV|BPF_X: case BPF_ALU|BPF_DIV|BPF_X:
if(X == 0) if (X == 0)
return (0); return 0;
A /= X; A /= X;
continue; continue;
case BPF_ALU|BPF_DIV|BPF_K: case BPF_ALU|BPF_DIV|BPF_K:
if(fentry->k == 0) if (fentry->k == 0)
return (0); return 0;
A /= fentry->k; A /= fentry->k;
continue; continue;
case BPF_ALU|BPF_AND|BPF_X: case BPF_ALU|BPF_AND|BPF_X:
A &= X; A &= X;
continue; continue;
case BPF_ALU|BPF_AND|BPF_K: case BPF_ALU|BPF_AND|BPF_K:
A &= fentry->k; A &= fentry->k;
continue; continue;
case BPF_ALU|BPF_OR|BPF_X: case BPF_ALU|BPF_OR|BPF_X:
A |= X; A |= X;
continue; continue;
case BPF_ALU|BPF_OR|BPF_K: case BPF_ALU|BPF_OR|BPF_K:
A |= fentry->k; A |= fentry->k;
continue; continue;
case BPF_ALU|BPF_LSH|BPF_X: case BPF_ALU|BPF_LSH|BPF_X:
A <<= X; A <<= X;
continue; continue;
case BPF_ALU|BPF_LSH|BPF_K: case BPF_ALU|BPF_LSH|BPF_K:
A <<= fentry->k; A <<= fentry->k;
continue; continue;
case BPF_ALU|BPF_RSH|BPF_X: case BPF_ALU|BPF_RSH|BPF_X:
A >>= X; A >>= X;
continue; continue;
case BPF_ALU|BPF_RSH|BPF_K: case BPF_ALU|BPF_RSH|BPF_K:
A >>= fentry->k; A >>= fentry->k;
continue; continue;
case BPF_ALU|BPF_NEG: case BPF_ALU|BPF_NEG:
A = -A; A = -A;
continue; continue;
case BPF_JMP|BPF_JA: case BPF_JMP|BPF_JA:
pc += fentry->k; pc += fentry->k;
continue; continue;
case BPF_JMP|BPF_JGT|BPF_K: case BPF_JMP|BPF_JGT|BPF_K:
pc += (A > fentry->k) ? fentry->jt : fentry->jf; pc += (A > fentry->k) ? fentry->jt : fentry->jf;
continue; continue;
case BPF_JMP|BPF_JGE|BPF_K: case BPF_JMP|BPF_JGE|BPF_K:
pc += (A >= fentry->k) ? fentry->jt : fentry->jf; pc += (A >= fentry->k) ? fentry->jt : fentry->jf;
continue; continue;
case BPF_JMP|BPF_JEQ|BPF_K: case BPF_JMP|BPF_JEQ|BPF_K:
pc += (A == fentry->k) ? fentry->jt : fentry->jf; pc += (A == fentry->k) ? fentry->jt : fentry->jf;
continue; continue;
case BPF_JMP|BPF_JSET|BPF_K: case BPF_JMP|BPF_JSET|BPF_K:
pc += (A & fentry->k) ? fentry->jt : fentry->jf; pc += (A & fentry->k) ? fentry->jt : fentry->jf;
continue; continue;
case BPF_JMP|BPF_JGT|BPF_X: case BPF_JMP|BPF_JGT|BPF_X:
pc += (A > X) ? fentry->jt : fentry->jf; pc += (A > X) ? fentry->jt : fentry->jf;
continue; continue;
case BPF_JMP|BPF_JGE|BPF_X: case BPF_JMP|BPF_JGE|BPF_X:
pc += (A >= X) ? fentry->jt : fentry->jf; pc += (A >= X) ? fentry->jt : fentry->jf;
continue; continue;
case BPF_JMP|BPF_JEQ|BPF_X: case BPF_JMP|BPF_JEQ|BPF_X:
pc += (A == X) ? fentry->jt : fentry->jf; pc += (A == X) ? fentry->jt : fentry->jf;
continue; continue;
case BPF_JMP|BPF_JSET|BPF_X: case BPF_JMP|BPF_JSET|BPF_X:
pc += (A & X) ? fentry->jt : fentry->jf; pc += (A & X) ? fentry->jt : fentry->jf;
continue; continue;
case BPF_LD|BPF_W|BPF_ABS: case BPF_LD|BPF_W|BPF_ABS:
k = fentry->k; k = fentry->k;
load_w: load_w:
if(k >= 0 && (unsigned int)(k+sizeof(u32)) <= len) { if (k >= 0 && (unsigned int)(k+sizeof(u32)) <= len) {
A = ntohl(*(u32*)&data[k]); A = ntohl(*(u32*)&data[k]);
continue; continue;
} }
if (k<0) { if (k < 0) {
u8 *ptr; u8 *ptr;
if (k>=SKF_AD_OFF) if (k >= SKF_AD_OFF)
break; break;
if ((ptr = load_pointer(skb, k)) != NULL) { ptr = load_pointer(skb, k);
if (ptr) {
A = ntohl(*(u32*)ptr); A = ntohl(*(u32*)ptr);
continue; continue;
} }
...@@ -219,20 +190,20 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) ...@@ -219,20 +190,20 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
} }
} }
return 0; return 0;
case BPF_LD|BPF_H|BPF_ABS: case BPF_LD|BPF_H|BPF_ABS:
k = fentry->k; k = fentry->k;
load_h: load_h:
if(k >= 0 && (unsigned int) (k + sizeof(u16)) <= len) { if (k >= 0 && (unsigned int)(k + sizeof(u16)) <= len) {
A = ntohs(*(u16*)&data[k]); A = ntohs(*(u16*)&data[k]);
continue; continue;
} }
if (k<0) { if (k < 0) {
u8 *ptr; u8 *ptr;
if (k>=SKF_AD_OFF) if (k >= SKF_AD_OFF)
break; break;
if ((ptr = load_pointer(skb, k)) != NULL) { ptr = load_pointer(skb, k);
if (ptr) {
A = ntohs(*(u16*)ptr); A = ntohs(*(u16*)ptr);
continue; continue;
} }
...@@ -244,20 +215,20 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) ...@@ -244,20 +215,20 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
} }
} }
return 0; return 0;
case BPF_LD|BPF_B|BPF_ABS: case BPF_LD|BPF_B|BPF_ABS:
k = fentry->k; k = fentry->k;
load_b: load_b:
if(k >= 0 && (unsigned int)k < len) { if (k >= 0 && (unsigned int)k < len) {
A = data[k]; A = data[k];
continue; continue;
} }
if (k<0) { if (k < 0) {
u8 *ptr; u8 *ptr;
if (k>=SKF_AD_OFF) if (k >= SKF_AD_OFF)
break; break;
if ((ptr = load_pointer(skb, k)) != NULL) { ptr = load_pointer(skb, k);
if (ptr) {
A = *ptr; A = *ptr;
continue; continue;
} }
...@@ -269,79 +240,63 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) ...@@ -269,79 +240,63 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
} }
} }
return 0; return 0;
case BPF_LD|BPF_W|BPF_LEN: case BPF_LD|BPF_W|BPF_LEN:
A = len; A = len;
continue; continue;
case BPF_LDX|BPF_W|BPF_LEN: case BPF_LDX|BPF_W|BPF_LEN:
X = len; X = len;
continue; continue;
case BPF_LD|BPF_W|BPF_IND: case BPF_LD|BPF_W|BPF_IND:
k = X + fentry->k; k = X + fentry->k;
goto load_w; goto load_w;
case BPF_LD|BPF_H|BPF_IND: case BPF_LD|BPF_H|BPF_IND:
k = X + fentry->k; k = X + fentry->k;
goto load_h; goto load_h;
case BPF_LD|BPF_B|BPF_IND: case BPF_LD|BPF_B|BPF_IND:
k = X + fentry->k; k = X + fentry->k;
goto load_b; goto load_b;
case BPF_LDX|BPF_B|BPF_MSH: case BPF_LDX|BPF_B|BPF_MSH:
k = fentry->k; k = fentry->k;
if(k >= 0 && (unsigned int)k >= len) if (k >= 0 && (unsigned int)k >= len)
return (0); return 0;
X = (data[k] & 0xf) << 2; X = (data[k] & 0xf) << 2;
continue; continue;
case BPF_LD|BPF_IMM: case BPF_LD|BPF_IMM:
A = fentry->k; A = fentry->k;
continue; continue;
case BPF_LDX|BPF_IMM: case BPF_LDX|BPF_IMM:
X = fentry->k; X = fentry->k;
continue; continue;
case BPF_LD|BPF_MEM: case BPF_LD|BPF_MEM:
A = mem[fentry->k]; A = mem[fentry->k];
continue; continue;
case BPF_LDX|BPF_MEM: case BPF_LDX|BPF_MEM:
X = mem[fentry->k]; X = mem[fentry->k];
continue; continue;
case BPF_MISC|BPF_TAX: case BPF_MISC|BPF_TAX:
X = A; X = A;
continue; continue;
case BPF_MISC|BPF_TXA: case BPF_MISC|BPF_TXA:
A = X; A = X;
continue; continue;
case BPF_RET|BPF_K: case BPF_RET|BPF_K:
return ((unsigned int)fentry->k); return ((unsigned int)fentry->k);
case BPF_RET|BPF_A: case BPF_RET|BPF_A:
return ((unsigned int)A); return ((unsigned int)A);
case BPF_ST: case BPF_ST:
mem[fentry->k] = A; mem[fentry->k] = A;
continue; continue;
case BPF_STX: case BPF_STX:
mem[fentry->k] = X; mem[fentry->k] = X;
continue; continue;
default: default:
/* Invalid instruction counts as RET */ /* Invalid instruction counts as RET */
return (0); return 0;
} }
/* Handle ancillary data, which are impossible /*
(or very difficult) to get parsing packet contents. * Handle ancillary data, which are impossible
* (or very difficult) to get parsing packet contents.
*/ */
switch (k-SKF_AD_OFF) { switch (k-SKF_AD_OFF) {
case SKF_AD_PROTOCOL: case SKF_AD_PROTOCOL:
...@@ -358,7 +313,7 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) ...@@ -358,7 +313,7 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
} }
} }
return (0); return 0;
} }
/** /**
...@@ -373,58 +328,39 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) ...@@ -373,58 +328,39 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
* *
* Returns 0 if the rule set is legal or a negative errno code if not. * Returns 0 if the rule set is legal or a negative errno code if not.
*/ */
int sk_chk_filter(struct sock_filter *filter, int flen) int sk_chk_filter(struct sock_filter *filter, int flen)
{ {
struct sock_filter *ftest; struct sock_filter *ftest;
int pc; int pc;
if ((unsigned int) flen >= (~0U / sizeof(struct sock_filter))) if ((unsigned int)flen >= (~0U / sizeof(struct sock_filter)))
return -EINVAL; return -EINVAL;
/* /* check the filter code now */
* Check the filter code now. for (pc = 0; pc < flen; pc++) {
*/ /* all jumps are forward as they are not signed */
for(pc = 0; pc < flen; pc++)
{
/*
* All jumps are forward as they are not signed
*/
ftest = &filter[pc]; ftest = &filter[pc];
if(BPF_CLASS(ftest->code) == BPF_JMP) if (BPF_CLASS(ftest->code) == BPF_JMP) {
{ /* but they mustn't jump off the end */
if (BPF_OP(ftest->code) == BPF_JA) {
/* /*
* But they mustn't jump off the end. * Note, the large ftest->k might cause loops.
*/ * Compare this with conditional jumps below,
if(BPF_OP(ftest->code) == BPF_JA) * where offsets are limited. --ANK (981016)
{
/* Note, the large ftest->k might cause
loops. Compare this with conditional
jumps below, where offsets are limited. --ANK (981016)
*/ */
if (ftest->k >= (unsigned)(flen-pc-1)) if (ftest->k >= (unsigned)(flen-pc-1))
return -EINVAL; return -EINVAL;
} } else {
else /* for conditionals both must be safe */
{ if (pc + ftest->jt +1 >= flen ||
/* pc + ftest->jf +1 >= flen)
* For conditionals both must be safe
*/
if(pc + ftest->jt +1 >= flen || pc + ftest->jf +1 >= flen)
return -EINVAL; return -EINVAL;
} }
} }
/* /* check that memory operations use valid addresses. */
* Check that memory operations use valid addresses. if (ftest->k >= BPF_MEMWORDS) {
*/ /* but it might not be a memory operation... */
if (ftest->k >= BPF_MEMWORDS)
{
/*
* But it might not be a memory operation...
*/
switch (ftest->code) { switch (ftest->code) {
case BPF_ST: case BPF_ST:
case BPF_STX: case BPF_STX:
...@@ -437,11 +373,10 @@ int sk_chk_filter(struct sock_filter *filter, int flen) ...@@ -437,11 +373,10 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
/* /*
* The program must end with a return. We don't care where they * The program must end with a return. We don't care where they
* jumped within the script (its always forwards) but in the * jumped within the script (its always forwards) but in the end
* end they _will_ hit this. * they _will_ hit this.
*/ */
return (BPF_CLASS(filter[flen - 1].code) == BPF_RET) ? 0 : -EINVAL;
return (BPF_CLASS(filter[flen - 1].code) == BPF_RET)?0:-EINVAL;
} }
/** /**
...@@ -454,7 +389,6 @@ int sk_chk_filter(struct sock_filter *filter, int flen) ...@@ -454,7 +389,6 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
* occurs or there is insufficient memory for the filter a negative * occurs or there is insufficient memory for the filter a negative
* errno code is returned. On success the return is zero. * errno code is returned. On success the return is zero.
*/ */
int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
{ {
struct sk_filter *fp; struct sk_filter *fp;
...@@ -463,12 +397,11 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) ...@@ -463,12 +397,11 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
/* Make sure new filter is there and in the right amounts. */ /* Make sure new filter is there and in the right amounts. */
if (fprog->filter == NULL || fprog->len > BPF_MAXINSNS) if (fprog->filter == NULL || fprog->len > BPF_MAXINSNS)
return (-EINVAL); return -EINVAL;
fp = (struct sk_filter *)sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL);
if(fp == NULL)
return (-ENOMEM);
fp = sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL);
if (!fp)
return -ENOMEM;
if (copy_from_user(fp->insns, fprog->filter, fsize)) { if (copy_from_user(fp->insns, fprog->filter, fsize)) {
sock_kfree_s(sk, fp, fsize+sizeof(*fp)); sock_kfree_s(sk, fp, fsize+sizeof(*fp));
return -EFAULT; return -EFAULT;
...@@ -477,7 +410,8 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) ...@@ -477,7 +410,8 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
atomic_set(&fp->refcnt, 1); atomic_set(&fp->refcnt, 1);
fp->len = fprog->len; fp->len = fprog->len;
if ((err = sk_chk_filter(fp->insns, fp->len))==0) { err = sk_chk_filter(fp->insns, fp->len);
if (!err) {
struct sk_filter *old_fp; struct sk_filter *old_fp;
spin_lock_bh(&sk->lock.slock); spin_lock_bh(&sk->lock.slock);
...@@ -489,6 +423,5 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) ...@@ -489,6 +423,5 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
if (fp) if (fp)
sk_filter_release(sk, fp); sk_filter_release(sk, fp);
return err;
return (err);
} }
...@@ -41,35 +41,35 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode) ...@@ -41,35 +41,35 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode)
{ {
int size, err, ct; int size, err, ct;
if(m->msg_namelen) if (m->msg_namelen) {
{ if (mode == VERIFY_READ) {
if(mode==VERIFY_READ) err = move_addr_to_kernel(m->msg_name, m->msg_namelen,
{ address);
err=move_addr_to_kernel(m->msg_name, m->msg_namelen, address); if (err < 0)
if(err<0) return err;
goto out;
}
m->msg_name = address; m->msg_name = address;
} else } else
m->msg_name = NULL; m->msg_name = NULL;
}
err = -EFAULT;
size = m->msg_iovlen * sizeof(struct iovec); size = m->msg_iovlen * sizeof(struct iovec);
if (copy_from_user(iov, m->msg_iov, size)) if (copy_from_user(iov, m->msg_iov, size))
goto out; return -EFAULT;
m->msg_iov=iov;
m->msg_iov = iov;
err = 0;
for (err = 0, ct = 0; ct < m->msg_iovlen; ct++) { for (ct = 0; ct < m->msg_iovlen; ct++) {
err += iov[ct].iov_len; err += iov[ct].iov_len;
/* Goal is not to verify user data, but to prevent returning /*
negative value, which is interpreted as errno. * Goal is not to verify user data, but to prevent returning
Overflow is still possible, but it is harmless. * negative value, which is interpreted as errno.
* Overflow is still possible, but it is harmless.
*/ */
if (err < 0) if (err < 0)
return -EMSGSIZE; return -EMSGSIZE;
} }
out:
return err; return err;
} }
...@@ -81,25 +81,20 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode) ...@@ -81,25 +81,20 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode)
int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len) int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len)
{ {
int err = -EFAULT; while (len > 0) {
if (iov->iov_len) {
while(len>0)
{
if(iov->iov_len)
{
int copy = min_t(unsigned int, iov->iov_len, len); int copy = min_t(unsigned int, iov->iov_len, len);
if (copy_to_user(iov->iov_base, kdata, copy)) if (copy_to_user(iov->iov_base, kdata, copy))
goto out; return -EFAULT;
kdata+=copy; kdata += copy;
len-=copy; len -= copy;
iov->iov_len-=copy; iov->iov_len -= copy;
iov->iov_base+=copy; iov->iov_base += copy;
} }
iov++; iov++;
} }
err = 0;
out: return 0;
return err;
} }
/* /*
...@@ -110,16 +105,14 @@ int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len) ...@@ -110,16 +105,14 @@ int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len)
void memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len) void memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len)
{ {
while(len>0) while (len > 0) {
{ if (iov->iov_len) {
if(iov->iov_len)
{
int copy = min_t(unsigned int, iov->iov_len, len); int copy = min_t(unsigned int, iov->iov_len, len);
memcpy(iov->iov_base, kdata, copy); memcpy(iov->iov_base, kdata, copy);
kdata+=copy; kdata += copy;
len-=copy; len -= copy;
iov->iov_len-=copy; iov->iov_len -= copy;
iov->iov_base+=copy; iov->iov_base += copy;
} }
iov++; iov++;
} }
...@@ -134,59 +127,47 @@ void memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len) ...@@ -134,59 +127,47 @@ void memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len)
int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len) int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len)
{ {
int err = -EFAULT; while (len > 0) {
if (iov->iov_len) {
while(len>0)
{
if(iov->iov_len)
{
int copy = min_t(unsigned int, len, iov->iov_len); int copy = min_t(unsigned int, len, iov->iov_len);
if (copy_from_user(kdata, iov->iov_base, copy)) if (copy_from_user(kdata, iov->iov_base, copy))
goto out; return -EFAULT;
len-=copy; len -= copy;
kdata+=copy; kdata += copy;
iov->iov_base+=copy; iov->iov_base += copy;
iov->iov_len-=copy; iov->iov_len -= copy;
} }
iov++; iov++;
} }
err = 0;
out:
return err;
}
return 0;
}
/* /*
* For use with ip_build_xmit * For use with ip_build_xmit
*/ */
int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset, int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
int len) int len)
{ {
int err = -EFAULT;
/* Skip over the finished iovecs */ /* Skip over the finished iovecs */
while(offset >= iov->iov_len) while (offset >= iov->iov_len) {
{
offset -= iov->iov_len; offset -= iov->iov_len;
iov++; iov++;
} }
while (len > 0) while (len > 0) {
{
u8 *base = iov->iov_base + offset; u8 *base = iov->iov_base + offset;
int copy = min_t(unsigned int, len, iov->iov_len - offset); int copy = min_t(unsigned int, len, iov->iov_len - offset);
offset = 0; offset = 0;
if (copy_from_user(kdata, base, copy)) if (copy_from_user(kdata, base, copy))
goto out; return -EFAULT;
len -= copy; len -= copy;
kdata += copy; kdata += copy;
iov++; iov++;
} }
err = 0;
out: return 0;
return err;
} }
/* /*
...@@ -197,7 +178,6 @@ int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset, ...@@ -197,7 +178,6 @@ int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
* ip_build_xmit must ensure that when fragmenting only the last * ip_build_xmit must ensure that when fragmenting only the last
* call to this function will be unaligned also. * call to this function will be unaligned also.
*/ */
int csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov, int csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov,
int offset, unsigned int len, int *csump) int offset, unsigned int len, int *csump)
{ {
...@@ -205,21 +185,19 @@ int csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov, ...@@ -205,21 +185,19 @@ int csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov,
int partial_cnt = 0, err = 0; int partial_cnt = 0, err = 0;
/* Skip over the finished iovecs */ /* Skip over the finished iovecs */
while (offset >= iov->iov_len) while (offset >= iov->iov_len) {
{
offset -= iov->iov_len; offset -= iov->iov_len;
iov++; iov++;
} }
while (len > 0) while (len > 0) {
{
u8 *base = iov->iov_base + offset; u8 *base = iov->iov_base + offset;
int copy = min_t(unsigned int, len, iov->iov_len - offset); int copy = min_t(unsigned int, len, iov->iov_len - offset);
offset = 0; offset = 0;
/* There is a remnant from previous iov. */ /* There is a remnant from previous iov. */
if (partial_cnt) if (partial_cnt) {
{
int par_len = 4 - partial_cnt; int par_len = 4 - partial_cnt;
/* iov component is too short ... */ /* iov component is too short ... */
...@@ -247,11 +225,9 @@ int csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov, ...@@ -247,11 +225,9 @@ int csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov,
partial_cnt = 0; partial_cnt = 0;
} }
if (len > copy) if (len > copy) {
{
partial_cnt = copy % 4; partial_cnt = copy % 4;
if (partial_cnt) if (partial_cnt) {
{
copy -= partial_cnt; copy -= partial_cnt;
if (copy_from_user(kdata + copy, base + copy, if (copy_from_user(kdata + copy, base + copy,
partial_cnt)) partial_cnt))
......
...@@ -343,6 +343,10 @@ config SYN_COOKIES ...@@ -343,6 +343,10 @@ config SYN_COOKIES
config INET_AH config INET_AH
tristate "IP: AH transformation" tristate "IP: AH transformation"
select CRYPTO
select CRYPTO_HMAC
select CRYPTO_MD5
select CRYPTO_SHA1
---help--- ---help---
Support for IPsec AH. Support for IPsec AH.
...@@ -350,6 +354,11 @@ config INET_AH ...@@ -350,6 +354,11 @@ config INET_AH
config INET_ESP config INET_ESP
tristate "IP: ESP transformation" tristate "IP: ESP transformation"
select CRYPTO
select CRYPTO_HMAC
select CRYPTO_MD5
select CRYPTO_SHA1
select CRYPTO_DES
---help--- ---help---
Support for IPsec ESP. Support for IPsec ESP.
...@@ -357,6 +366,8 @@ config INET_ESP ...@@ -357,6 +366,8 @@ config INET_ESP
config INET_IPCOMP config INET_IPCOMP
tristate "IP: IPComp transformation" tristate "IP: IPComp transformation"
select CRYPTO
select CRYPTO_DEFLATE
---help--- ---help---
Support for IP Paylod Compression (RFC3173), typically needed Support for IP Paylod Compression (RFC3173), typically needed
for IPsec. for IPsec.
......
...@@ -16,8 +16,8 @@ obj-$(CONFIG_IP_MROUTE) += ipmr.o ...@@ -16,8 +16,8 @@ obj-$(CONFIG_IP_MROUTE) += ipmr.o
obj-$(CONFIG_NET_IPIP) += ipip.o obj-$(CONFIG_NET_IPIP) += ipip.o
obj-$(CONFIG_NET_IPGRE) += ip_gre.o obj-$(CONFIG_NET_IPGRE) += ip_gre.o
obj-$(CONFIG_SYN_COOKIES) += syncookies.o obj-$(CONFIG_SYN_COOKIES) += syncookies.o
obj-$(CONFIG_INET_AH) += ah.o obj-$(CONFIG_INET_AH) += ah4.o
obj-$(CONFIG_INET_ESP) += esp.o obj-$(CONFIG_INET_ESP) += esp4.o
obj-$(CONFIG_INET_IPCOMP) += ipcomp.o obj-$(CONFIG_INET_IPCOMP) += ipcomp.o
obj-$(CONFIG_IP_PNP) += ipconfig.o obj-$(CONFIG_IP_PNP) += ipconfig.o
obj-$(CONFIG_NETFILTER) += netfilter/ obj-$(CONFIG_NETFILTER) += netfilter/
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
config IPV6_PRIVACY config IPV6_PRIVACY
bool "IPv6: Privacy Extensions (RFC 3041) support" bool "IPv6: Privacy Extensions (RFC 3041) support"
depends on IPV6 depends on IPV6
select CRYPTO
select CRYPTO_MD5
---help--- ---help---
Privacy Extensions for Stateless Address Autoconfiguration in IPv6 Privacy Extensions for Stateless Address Autoconfiguration in IPv6
support. With this option, additional periodically-alter support. With this option, additional periodically-alter
...@@ -20,6 +22,10 @@ config IPV6_PRIVACY ...@@ -20,6 +22,10 @@ config IPV6_PRIVACY
config INET6_AH config INET6_AH
tristate "IPv6: AH transformation" tristate "IPv6: AH transformation"
depends on IPV6 depends on IPV6
select CRYPTO
select CRYPTO_HMAC
select CRYPTO_MD5
select CRYPTO_SHA1
---help--- ---help---
Support for IPsec AH. Support for IPsec AH.
...@@ -28,6 +34,11 @@ config INET6_AH ...@@ -28,6 +34,11 @@ config INET6_AH
config INET6_ESP config INET6_ESP
tristate "IPv6: ESP transformation" tristate "IPv6: ESP transformation"
depends on IPV6 depends on IPV6
select CRYPTO
select CRYPTO_HMAC
select CRYPTO_MD5
select CRYPTO_SHA1
select CRYPTO_DES
---help--- ---help---
Support for IPsec ESP. Support for IPsec ESP.
...@@ -36,6 +47,8 @@ config INET6_ESP ...@@ -36,6 +47,8 @@ config INET6_ESP
config INET6_IPCOMP config INET6_IPCOMP
tristate "IPv6: IPComp transformation" tristate "IPv6: IPComp transformation"
depends on IPV6 depends on IPV6
select CRYPTO
select CRYPTO_DEFLATE
---help--- ---help---
Support for IP Paylod Compression (RFC3173), typically needed Support for IP Paylod Compression (RFC3173), typically needed
for IPsec. for IPsec.
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* *
* Janos Farkas : delete timer on ifdown * Janos Farkas : delete timer on ifdown
* <chexum@bankinf.banki.hu> * <chexum@bankinf.banki.hu>
* Andi Kleen : kill doube kfree on module * Andi Kleen : kill double kfree on module
* unload. * unload.
* Maciej W. Rozycki : FDDI support * Maciej W. Rozycki : FDDI support
* sekiya@USAGI : Don't send too many RS * sekiya@USAGI : Don't send too many RS
...@@ -343,6 +343,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) ...@@ -343,6 +343,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
"%s(): cannot create /proc/net/dev_snmp6/%s\n", "%s(): cannot create /proc/net/dev_snmp6/%s\n",
__FUNCTION__, dev->name)); __FUNCTION__, dev->name));
neigh_parms_release(&nd_tbl, ndev->nd_parms); neigh_parms_release(&nd_tbl, ndev->nd_parms);
ndev->dead = 1;
in6_dev_finish_destroy(ndev); in6_dev_finish_destroy(ndev);
return NULL; return NULL;
} }
...@@ -1256,7 +1257,7 @@ static void sit_route_add(struct net_device *dev) ...@@ -1256,7 +1257,7 @@ static void sit_route_add(struct net_device *dev)
rtmsg.rtmsg_type = RTMSG_NEWROUTE; rtmsg.rtmsg_type = RTMSG_NEWROUTE;
rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF; rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF;
/* prefix length - 96 bytes "::d.d.d.d" */ /* prefix length - 96 bits "::d.d.d.d" */
rtmsg.rtmsg_dst_len = 96; rtmsg.rtmsg_dst_len = 96;
rtmsg.rtmsg_flags = RTF_UP|RTF_NONEXTHOP; rtmsg.rtmsg_flags = RTF_UP|RTF_NONEXTHOP;
rtmsg.rtmsg_ifindex = dev->ifindex; rtmsg.rtmsg_ifindex = dev->ifindex;
......
...@@ -310,7 +310,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) ...@@ -310,7 +310,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
} else { } else {
if (addr_type != IPV6_ADDR_ANY) { if (addr_type != IPV6_ADDR_ANY) {
/* ipv4 addr of the socket is invalid. Only the /* ipv4 addr of the socket is invalid. Only the
* unpecified and mapped address have a v4 equivalent. * unspecified and mapped address have a v4 equivalent.
*/ */
v4addr = LOOPBACK4_IPV6; v4addr = LOOPBACK4_IPV6;
if (!(addr_type & IPV6_ADDR_MULTICAST)) { if (!(addr_type & IPV6_ADDR_MULTICAST)) {
......
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
#include <net/ip6_route.h> #include <net/ip6_route.h>
#define RT6_DEBUG 2 #define RT6_DEBUG 2
#undef CONFIG_IPV6_SUBTREES
#if RT6_DEBUG >= 3 #if RT6_DEBUG >= 3
#define RT6_TRACE(x...) printk(KERN_DEBUG x) #define RT6_TRACE(x...) printk(KERN_DEBUG x)
...@@ -594,8 +593,8 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh, ...@@ -594,8 +593,8 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh,
is orphan. If it is, shoot it. is orphan. If it is, shoot it.
*/ */
st_failure: st_failure:
if (fn && !(fn->fn_flags&RTN_RTINFO|RTN_ROOT)) if (fn && !(fn->fn_flags & (RTN_RTINFO|RTN_ROOT)))
fib_repair_tree(fn); fib6_repair_tree(fn);
dst_free(&rt->u.dst); dst_free(&rt->u.dst);
return err; return err;
#endif #endif
...@@ -896,6 +895,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, ...@@ -896,6 +895,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
*rtp = rt->u.next; *rtp = rt->u.next;
rt->rt6i_node = NULL; rt->rt6i_node = NULL;
rt6_stats.fib_rt_entries--; rt6_stats.fib_rt_entries--;
rt6_stats.fib_discarded_routes++;
/* Adjust walkers */ /* Adjust walkers */
read_lock(&fib6_walker_lock); read_lock(&fib6_walker_lock);
......
...@@ -336,7 +336,7 @@ static int rt6_ins(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) ...@@ -336,7 +336,7 @@ static int rt6_ins(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
return err; return err;
} }
/* No rt6_lock! If COW faild, the function returns dead route entry /* No rt6_lock! If COW failed, the function returns dead route entry
with dst->error set to errno value. with dst->error set to errno value.
*/ */
...@@ -1786,11 +1786,12 @@ extern struct rt6_statistics rt6_stats; ...@@ -1786,11 +1786,12 @@ extern struct rt6_statistics rt6_stats;
static int rt6_stats_seq_show(struct seq_file *seq, void *v) static int rt6_stats_seq_show(struct seq_file *seq, void *v)
{ {
seq_printf(seq, "%04x %04x %04x %04x %04x %04x\n", seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n",
rt6_stats.fib_nodes, rt6_stats.fib_route_nodes, rt6_stats.fib_nodes, rt6_stats.fib_route_nodes,
rt6_stats.fib_rt_alloc, rt6_stats.fib_rt_entries, rt6_stats.fib_rt_alloc, rt6_stats.fib_rt_entries,
rt6_stats.fib_rt_cache, rt6_stats.fib_rt_cache,
atomic_read(&ip6_dst_ops.entries)); atomic_read(&ip6_dst_ops.entries),
rt6_stats.fib_discarded_routes);
return 0; return 0;
} }
......
...@@ -254,7 +254,6 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -254,7 +254,6 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
struct inet_opt *inet = inet_sk(sk); struct inet_opt *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
struct in6_addr *daddr; struct in6_addr *daddr;
struct in6_addr saddr;
struct dst_entry *dst; struct dst_entry *dst;
struct flowi fl; struct flowi fl;
struct ip6_flowlabel *flowlabel = NULL; struct ip6_flowlabel *flowlabel = NULL;
...@@ -355,7 +354,7 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -355,7 +354,7 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
fl.proto = IPPROTO_UDP; fl.proto = IPPROTO_UDP;
ipv6_addr_copy(&fl.fl6_dst, &np->daddr); ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
ipv6_addr_copy(&fl.fl6_src, &saddr); ipv6_addr_copy(&fl.fl6_src, &np->saddr);
fl.oif = sk->bound_dev_if; fl.oif = sk->bound_dev_if;
fl.fl_ip_dport = inet->dport; fl.fl_ip_dport = inet->dport;
fl.fl_ip_sport = inet->sport; fl.fl_ip_sport = inet->sport;
...@@ -381,20 +380,23 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -381,20 +380,23 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
return err; return err;
} }
ip6_dst_store(sk, dst, &fl.fl6_dst);
/* get the source address used in the appropriate device */ /* get the source address used in the appropriate device */
err = ipv6_get_saddr(dst, daddr, &saddr); err = ipv6_get_saddr(dst, daddr, &fl.fl6_src);
if (err == 0) { if (err == 0) {
if (ipv6_addr_any(&np->saddr)) if (ipv6_addr_any(&np->saddr))
ipv6_addr_copy(&np->saddr, &saddr); ipv6_addr_copy(&np->saddr, &fl.fl6_src);
if (ipv6_addr_any(&np->rcv_saddr)) { if (ipv6_addr_any(&np->rcv_saddr)) {
ipv6_addr_copy(&np->rcv_saddr, &saddr); ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src);
inet->rcv_saddr = LOOPBACK4_IPV6; inet->rcv_saddr = LOOPBACK4_IPV6;
} }
ip6_dst_store(sk, dst,
!ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
&np->daddr : NULL);
sk->state = TCP_ESTABLISHED; sk->state = TCP_ESTABLISHED;
} }
fl6_sock_release(flowlabel); fl6_sock_release(flowlabel);
......
...@@ -146,7 +146,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int ...@@ -146,7 +146,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
memcpy(&dst_prev->metrics, &rt->u.dst.metrics, sizeof(dst_prev->metrics)); memcpy(&dst_prev->metrics, &rt->u.dst.metrics, sizeof(dst_prev->metrics));
dst_prev->path = &rt->u.dst; dst_prev->path = &rt->u.dst;
/* Copy neighbout for reachability confirmation */ /* Copy neighbour for reachability confirmation */
dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour); dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour);
dst_prev->input = rt->u.dst.input; dst_prev->input = rt->u.dst.input;
dst_prev->output = dst_prev->xfrm->type->output; dst_prev->output = dst_prev->xfrm->type->output;
......
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