提交 12074a35 编写于 作者: L Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

......@@ -5,6 +5,13 @@
menu "ATM drivers"
depends on NETDEVICES && ATM
config ATM_DUMMY
tristate "Dummy ATM driver"
depends on ATM
help
Dummy ATM driver. Useful for proxy signalling, testing,
and development. If unsure, say N.
config ATM_TCP
tristate "ATM over TCP"
depends on INET && ATM
......
......@@ -31,6 +31,7 @@ ifeq ($(CONFIG_ATM_IDT77252_USE_SUNI),y)
obj-$(CONFIG_ATM_IDT77252) += suni.o
endif
obj-$(CONFIG_ATM_DUMMY) += adummy.o
obj-$(CONFIG_ATM_TCP) += atmtcp.o
obj-$(CONFIG_ATM_FIRESTREAM) += firestream.o
obj-$(CONFIG_ATM_LANAI) += lanai.o
......
/*
* adummy.c: a dummy ATM driver
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/pci.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
#include <linux/atmdev.h>
#include <linux/atm.h>
#include <linux/sonet.h>
/* version definition */
#define DRV_VERSION "1.0"
#define DEV_LABEL "adummy"
#define ADUMMY_DEV(dev) ((struct adummy_dev *) (dev)->dev_data)
struct adummy_dev {
struct atm_dev *atm_dev;
struct list_head entry;
};
/* globals */
static LIST_HEAD(adummy_devs);
static int __init
adummy_start(struct atm_dev *dev)
{
dev->ci_range.vpi_bits = 4;
dev->ci_range.vci_bits = 12;
return 0;
}
static int
adummy_open(struct atm_vcc *vcc)
{
short vpi = vcc->vpi;
int vci = vcc->vci;
if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
return 0;
set_bit(ATM_VF_ADDR, &vcc->flags);
set_bit(ATM_VF_READY, &vcc->flags);
return 0;
}
static void
adummy_close(struct atm_vcc *vcc)
{
clear_bit(ATM_VF_READY, &vcc->flags);
clear_bit(ATM_VF_ADDR, &vcc->flags);
}
static int
adummy_send(struct atm_vcc *vcc, struct sk_buff *skb)
{
if (vcc->pop)
vcc->pop(vcc, skb);
else
dev_kfree_skb_any(skb);
atomic_inc(&vcc->stats->tx);
return 0;
}
static int
adummy_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
{
int left = *pos;
if (!left--)
return sprintf(page, "version %s\n", DRV_VERSION);
return 0;
}
static struct atmdev_ops adummy_ops =
{
.open = adummy_open,
.close = adummy_close,
.send = adummy_send,
.proc_read = adummy_proc_read,
.owner = THIS_MODULE
};
static int __init adummy_init(void)
{
struct atm_dev *atm_dev;
struct adummy_dev *adummy_dev;
int err = 0;
printk(KERN_ERR "adummy: version %s\n", DRV_VERSION);
adummy_dev = (struct adummy_dev *) kmalloc(sizeof(struct adummy_dev),
GFP_KERNEL);
if (!adummy_dev) {
printk(KERN_ERR DEV_LABEL ": kmalloc() failed\n");
err = -ENOMEM;
goto out;
}
memset(adummy_dev, 0, sizeof(struct adummy_dev));
atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, 0);
if (!atm_dev) {
printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
err = -ENODEV;
goto out_kfree;
}
adummy_dev->atm_dev = atm_dev;
atm_dev->dev_data = adummy_dev;
if (adummy_start(atm_dev)) {
printk(KERN_ERR DEV_LABEL ": adummy_start() failed\n");
err = -ENODEV;
goto out_unregister;
}
list_add(&adummy_dev->entry, &adummy_devs);
out:
return err;
out_unregister:
atm_dev_deregister(atm_dev);
out_kfree:
kfree(adummy_dev);
goto out;
}
static void __exit adummy_cleanup(void)
{
struct adummy_dev *adummy_dev, *next;
list_for_each_entry_safe(adummy_dev, next, &adummy_devs, entry) {
atm_dev_deregister(adummy_dev->atm_dev);
kfree(adummy_dev);
}
}
module_init(adummy_init);
module_exit(adummy_cleanup);
MODULE_AUTHOR("chas williams <chas@cmf.nrl.navy.mil>");
MODULE_DESCRIPTION("dummy ATM driver");
MODULE_LICENSE("GPL");
/* drivers/atm/atmdev_init.c - ATM device driver initialization */
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
#include <linux/config.h>
#include <linux/init.h>
#ifdef CONFIG_ATM_ZATM
extern int zatm_detect(void);
#endif
#ifdef CONFIG_ATM_AMBASSADOR
extern int amb_detect(void);
#endif
#ifdef CONFIG_ATM_HORIZON
extern int hrz_detect(void);
#endif
#ifdef CONFIG_ATM_FORE200E
extern int fore200e_detect(void);
#endif
#ifdef CONFIG_ATM_LANAI
extern int lanai_detect(void);
#endif
/*
* For historical reasons, atmdev_init returns the number of devices found.
* Note that some detections may not go via atmdev_init (e.g. eni.c), so this
* number is meaningless.
*/
int __init atmdev_init(void)
{
int devs;
devs = 0;
#ifdef CONFIG_ATM_ZATM
devs += zatm_detect();
#endif
#ifdef CONFIG_ATM_AMBASSADOR
devs += amb_detect();
#endif
#ifdef CONFIG_ATM_HORIZON
devs += hrz_detect();
#endif
#ifdef CONFIG_ATM_FORE200E
devs += fore200e_detect();
#endif
#ifdef CONFIG_ATM_LANAI
devs += lanai_detect();
#endif
return devs;
}
......@@ -246,10 +246,6 @@ static void atmtcp_c_close(struct atm_vcc *vcc)
{
struct atm_dev *atmtcp_dev;
struct atmtcp_dev_data *dev_data;
struct sock *s;
struct hlist_node *node;
struct atm_vcc *walk;
int i;
atmtcp_dev = (struct atm_dev *) vcc->dev_data;
dev_data = PRIV(atmtcp_dev);
......@@ -257,20 +253,8 @@ static void atmtcp_c_close(struct atm_vcc *vcc)
if (dev_data->persist) return;
atmtcp_dev->dev_data = NULL;
kfree(dev_data);
shutdown_atm_dev(atmtcp_dev);
atm_dev_deregister(atmtcp_dev);
vcc->dev_data = NULL;
read_lock(&vcc_sklist_lock);
for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
struct hlist_head *head = &vcc_hash[i];
sk_for_each(s, node, head) {
walk = atm_sk(s);
if (walk->dev != atmtcp_dev)
continue;
wake_up(s->sk_sleep);
}
}
read_unlock(&vcc_sklist_lock);
module_put(THIS_MODULE);
}
......@@ -450,7 +434,7 @@ static int atmtcp_remove_persistent(int itf)
if (PRIV(dev)->vcc) return 0;
kfree(dev_data);
atm_dev_put(dev);
shutdown_atm_dev(dev);
atm_dev_deregister(dev);
return 0;
}
......
......@@ -39,7 +39,7 @@
* o lanai_change_qos() isn't written yet
*
* o There aren't any ioctl's yet -- I'd like to eventually support
* setting loopback and LED modes that way. (see lanai_ioctl)
* setting loopback and LED modes that way.
*
* o If the segmentation engine or DMA gets shut down we should restart
* card as per section 17.0i. (see lanai_reset)
......@@ -305,7 +305,7 @@ struct lanai_dev {
* vci with their bit set
*/
static void vci_bitfield_iterate(struct lanai_dev *lanai,
/*const*/ unsigned long *lp,
const unsigned long *lp,
void (*func)(struct lanai_dev *,vci_t vci))
{
vci_t vci = find_first_bit(lp, NUM_VCI);
......@@ -951,7 +951,7 @@ static int __devinit eeprom_read(struct lanai_dev *lanai)
/* read a big-endian 4-byte value out of eeprom */
static inline u32 eeprom_be4(const struct lanai_dev *lanai, int address)
{
return be32_to_cpup((u32 *) (&lanai->eeprom[address]));
return be32_to_cpup((const u32 *) &lanai->eeprom[address]);
}
/* Checksum/validate EEPROM contents */
......@@ -1160,7 +1160,7 @@ static inline int vcc_tx_space(const struct lanai_vcc *lvcc, int endptr)
}
/* test if VCC is currently backlogged */
static inline int vcc_is_backlogged(/*const*/ struct lanai_vcc *lvcc)
static inline int vcc_is_backlogged(const struct lanai_vcc *lvcc)
{
return !skb_queue_empty(&lvcc->tx.backlog);
}
......@@ -1395,7 +1395,8 @@ static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr)
{
int size;
struct sk_buff *skb;
/*const*/ u32 *x, *end = &lvcc->rx.buf.start[endptr * 4];
const u32 *x;
u32 *end = &lvcc->rx.buf.start[endptr * 4];
int n = ((unsigned long) end) - ((unsigned long) lvcc->rx.buf.ptr);
if (n < 0)
n += lanai_buf_size(&lvcc->rx.buf);
......@@ -2111,7 +2112,7 @@ static int lanai_normalize_ci(struct lanai_dev *lanai,
* shifted by that much as we compute
*
*/
static int pcr_to_cbricg(/*const*/ struct atm_qos *qos)
static int pcr_to_cbricg(const struct atm_qos *qos)
{
int rounddown = 0; /* 1 = Round PCR down, i.e. round ICG _up_ */
int x, icg, pcr = atm_pcr_goal(&qos->txtp);
......@@ -2434,93 +2435,6 @@ static int lanai_open(struct atm_vcc *atmvcc)
return result;
}
#if 0
/* ioctl operations for card */
/* NOTE: these are all DEBUGGING ONLY currently */
static int lanai_ioctl(struct atm_dev *atmdev, unsigned int cmd, void __user *arg)
{
int result = 0;
struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
switch(cmd) {
case 2106275:
shutdown_atm_dev(atmdev);
return 0;
case 2200000: {
unsigned long flags;
spin_lock_irqsave(&lanai->servicelock, flags);
run_service(lanai);
spin_unlock_irqrestore(&lanai->servicelock, flags);
return 0; }
case 2200002:
get_statistics(lanai);
return 0;
case 2200003: {
unsigned int i;
for (i = 0; i <= 0x5C ; i += 4) {
if (i==0x48) /* Write-only butt reg */
continue;
printk(KERN_CRIT DEV_LABEL " 0x%02X: "
"0x%08X\n", i,
(unsigned int) readl(lanai->base + i));
barrier(); mb();
pcistatus_check(lanai, 0);
barrier(); mb();
}
return 0; }
case 2200004: {
u8 b;
u16 w;
u32 dw;
struct pci_dev *pci = lanai->pci;
(void) pci_read_config_word(pci, PCI_VENDOR_ID, &w);
DPRINTK("vendor = 0x%X\n", (unsigned int) w);
(void) pci_read_config_word(pci, PCI_DEVICE_ID, &w);
DPRINTK("device = 0x%X\n", (unsigned int) w);
(void) pci_read_config_word(pci, PCI_COMMAND, &w);
DPRINTK("command = 0x%X\n", (unsigned int) w);
(void) pci_read_config_word(pci, PCI_STATUS, &w);
DPRINTK("status = 0x%X\n", (unsigned int) w);
(void) pci_read_config_dword(pci,
PCI_CLASS_REVISION, &dw);
DPRINTK("class/revision = 0x%X\n", (unsigned int) dw);
(void) pci_read_config_byte(pci,
PCI_CACHE_LINE_SIZE, &b);
DPRINTK("cache line size = 0x%X\n", (unsigned int) b);
(void) pci_read_config_byte(pci, PCI_LATENCY_TIMER, &b);
DPRINTK("latency = %d (0x%X)\n",
(int) b, (unsigned int) b);
(void) pci_read_config_byte(pci, PCI_HEADER_TYPE, &b);
DPRINTK("header type = 0x%X\n", (unsigned int) b);
(void) pci_read_config_byte(pci, PCI_BIST, &b);
DPRINTK("bist = 0x%X\n", (unsigned int) b);
/* skipping a few here */
(void) pci_read_config_byte(pci,
PCI_INTERRUPT_LINE, &b);
DPRINTK("pci_int_line = 0x%X\n", (unsigned int) b);
(void) pci_read_config_byte(pci,
PCI_INTERRUPT_PIN, &b);
DPRINTK("pci_int_pin = 0x%X\n", (unsigned int) b);
(void) pci_read_config_byte(pci, PCI_MIN_GNT, &b);
DPRINTK("min_gnt = 0x%X\n", (unsigned int) b);
(void) pci_read_config_byte(pci, PCI_MAX_LAT, &b);
DPRINTK("max_lat = 0x%X\n", (unsigned int) b); }
return 0;
#ifdef USE_POWERDOWN
case 2200005:
DPRINTK("Coming out of powerdown\n");
lanai->conf1 &= ~CONFIG1_POWERDOWN;
conf1_write(lanai);
return 0;
#endif
default:
result = -ENOIOCTLCMD;
}
return result;
}
#else /* !0 */
#define lanai_ioctl NULL
#endif /* 0 */
static int lanai_send(struct atm_vcc *atmvcc, struct sk_buff *skb)
{
struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data;
......@@ -2678,7 +2592,6 @@ static const struct atmdev_ops ops = {
.dev_close = lanai_dev_close,
.open = lanai_open,
.close = lanai_close,
.ioctl = lanai_ioctl,
.getsockopt = NULL,
.setsockopt = NULL,
.send = lanai_send,
......@@ -2760,6 +2673,7 @@ static void __exit lanai_module_exit(void)
* gone, so there isn't much to do
*/
DPRINTK("cleanup_module()\n");
pci_unregister_driver(&lanai_driver);
}
module_init(lanai_module_init);
......
......@@ -879,7 +879,7 @@ static int usbatm_atm_init(struct usbatm_data *instance)
fail:
instance->atm_dev = NULL;
shutdown_atm_dev(atm_dev); /* usbatm_atm_dev_close will eventually be called */
atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */
return ret;
}
......@@ -1164,7 +1164,7 @@ void usbatm_usb_disconnect(struct usb_interface *intf)
/* ATM finalize */
if (instance->atm_dev)
shutdown_atm_dev(instance->atm_dev);
atm_dev_deregister(instance->atm_dev);
usbatm_put_instance(instance); /* taken in usbatm_usb_probe */
}
......
......@@ -7,7 +7,6 @@
#define LINUX_ATMDEV_H
#include <linux/config.h>
#include <linux/atmapi.h>
#include <linux/atm.h>
#include <linux/atmioc.h>
......@@ -210,6 +209,7 @@ struct atm_cirange {
#ifdef __KERNEL__
#include <linux/config.h>
#include <linux/wait.h> /* wait_queue_head_t */
#include <linux/time.h> /* struct timeval */
#include <linux/net.h>
......@@ -274,7 +274,7 @@ enum {
enum {
ATM_DF_CLOSE, /* close device when last VCC is closed */
ATM_DF_REMOVED, /* device was removed from atm_devs list */
};
......@@ -415,7 +415,6 @@ struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops,
int number,unsigned long *flags); /* number == -1: pick first available */
struct atm_dev *atm_dev_lookup(int number);
void atm_dev_deregister(struct atm_dev *dev);
void shutdown_atm_dev(struct atm_dev *dev);
void vcc_insert_socket(struct sock *sk);
......@@ -457,18 +456,19 @@ static inline void atm_dev_hold(struct atm_dev *dev)
static inline void atm_dev_put(struct atm_dev *dev)
{
atomic_dec(&dev->refcnt);
if ((atomic_read(&dev->refcnt) == 1) &&
test_bit(ATM_DF_CLOSE,&dev->flags))
shutdown_atm_dev(dev);
if (atomic_dec_and_test(&dev->refcnt)) {
BUG_ON(!test_bit(ATM_DF_REMOVED, &dev->flags));
if (dev->ops->dev_close)
dev->ops->dev_close(dev);
kfree(dev);
}
}
int atm_charge(struct atm_vcc *vcc,int truesize);
struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size,
gfp_t gfp_flags);
int atm_pcr_goal(struct atm_trafprm *tp);
int atm_pcr_goal(const struct atm_trafprm *tp);
void vcc_release_async(struct atm_vcc *vcc, int reply);
......
......@@ -74,11 +74,14 @@ struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size,
*/
int atm_pcr_goal(struct atm_trafprm *tp)
int atm_pcr_goal(const struct atm_trafprm *tp)
{
if (tp->pcr && tp->pcr != ATM_MAX_PCR) return -tp->pcr;
if (tp->min_pcr && !tp->pcr) return tp->min_pcr;
if (tp->max_pcr != ATM_MAX_PCR) return -tp->max_pcr;
if (tp->pcr && tp->pcr != ATM_MAX_PCR)
return -tp->pcr;
if (tp->min_pcr && !tp->pcr)
return tp->min_pcr;
if (tp->max_pcr != ATM_MAX_PCR)
return -tp->max_pcr;
return 0;
}
......
......@@ -221,6 +221,29 @@ void vcc_release_async(struct atm_vcc *vcc, int reply)
EXPORT_SYMBOL(vcc_release_async);
void atm_dev_release_vccs(struct atm_dev *dev)
{
int i;
write_lock_irq(&vcc_sklist_lock);
for (i = 0; i < VCC_HTABLE_SIZE; i++) {
struct hlist_head *head = &vcc_hash[i];
struct hlist_node *node, *tmp;
struct sock *s;
struct atm_vcc *vcc;
sk_for_each_safe(s, node, tmp, head) {
vcc = atm_sk(s);
if (vcc->dev == dev) {
vcc_release_async(vcc, -EPIPE);
sk_del_node_init(s);
}
}
}
write_unlock_irq(&vcc_sklist_lock);
}
static int adjust_tp(struct atm_trafprm *tp,unsigned char aal)
{
int max_sdu;
......@@ -332,12 +355,13 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, short vpi,
return -EINVAL;
if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE))
return -EPERM;
error = 0;
error = -ENODEV;
if (!try_module_get(dev->ops->owner))
return -ENODEV;
return error;
vcc->dev = dev;
write_lock_irq(&vcc_sklist_lock);
if ((error = find_ci(vcc, &vpi, &vci))) {
if (test_bit(ATM_DF_REMOVED, &dev->flags) ||
(error = find_ci(vcc, &vpi, &vci))) {
write_unlock_irq(&vcc_sklist_lock);
goto fail_module_put;
}
......@@ -423,33 +447,23 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci)
if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS ||
vcc->qos.rxtp.traffic_class == ATM_ANYCLASS)
return -EINVAL;
if (itf != ATM_ITF_ANY) {
dev = atm_dev_lookup(itf);
if (!dev)
return -ENODEV;
error = __vcc_connect(vcc, dev, vpi, vci);
if (error) {
atm_dev_put(dev);
return error;
}
if (likely(itf != ATM_ITF_ANY)) {
dev = try_then_request_module(atm_dev_lookup(itf), "atm-device-%d", itf);
} else {
struct list_head *p, *next;
dev = NULL;
spin_lock(&atm_dev_lock);
list_for_each_safe(p, next, &atm_devs) {
dev = list_entry(p, struct atm_dev, dev_list);
down(&atm_dev_mutex);
if (!list_empty(&atm_devs)) {
dev = list_entry(atm_devs.next, struct atm_dev, dev_list);
atm_dev_hold(dev);
spin_unlock(&atm_dev_lock);
if (!__vcc_connect(vcc, dev, vpi, vci))
break;
atm_dev_put(dev);
dev = NULL;
spin_lock(&atm_dev_lock);
}
spin_unlock(&atm_dev_lock);
if (!dev)
return -ENODEV;
up(&atm_dev_mutex);
}
if (!dev)
return -ENODEV;
error = __vcc_connect(vcc, dev, vpi, vci);
if (error) {
atm_dev_put(dev);
return error;
}
if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC)
set_bit(ATM_VF_PARTIAL,&vcc->flags);
......
......@@ -47,4 +47,6 @@ static inline void atm_proc_exit(void)
/* SVC */
int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos);
void atm_dev_release_vccs(struct atm_dev *dev);
#endif
......@@ -25,7 +25,7 @@
LIST_HEAD(atm_devs);
DEFINE_SPINLOCK(atm_dev_lock);
DECLARE_MUTEX(atm_dev_mutex);
static struct atm_dev *__alloc_atm_dev(const char *type)
{
......@@ -52,7 +52,7 @@ static struct atm_dev *__atm_dev_lookup(int number)
list_for_each(p, &atm_devs) {
dev = list_entry(p, struct atm_dev, dev_list);
if ((dev->ops) && (dev->number == number)) {
if (dev->number == number) {
atm_dev_hold(dev);
return dev;
}
......@@ -64,12 +64,13 @@ struct atm_dev *atm_dev_lookup(int number)
{
struct atm_dev *dev;
spin_lock(&atm_dev_lock);
down(&atm_dev_mutex);
dev = __atm_dev_lookup(number);
spin_unlock(&atm_dev_lock);
up(&atm_dev_mutex);
return dev;
}
struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
int number, unsigned long *flags)
{
......@@ -81,11 +82,11 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
type);
return NULL;
}
spin_lock(&atm_dev_lock);
down(&atm_dev_mutex);
if (number != -1) {
if ((inuse = __atm_dev_lookup(number))) {
atm_dev_put(inuse);
spin_unlock(&atm_dev_lock);
up(&atm_dev_mutex);
kfree(dev);
return NULL;
}
......@@ -105,19 +106,17 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
memset(&dev->flags, 0, sizeof(dev->flags));
memset(&dev->stats, 0, sizeof(dev->stats));
atomic_set(&dev->refcnt, 1);
list_add_tail(&dev->dev_list, &atm_devs);
spin_unlock(&atm_dev_lock);
if (atm_proc_dev_register(dev) < 0) {
printk(KERN_ERR "atm_dev_register: "
"atm_proc_dev_register failed for dev %s\n",
type);
spin_lock(&atm_dev_lock);
list_del(&dev->dev_list);
spin_unlock(&atm_dev_lock);
up(&atm_dev_mutex);
kfree(dev);
return NULL;
}
list_add_tail(&dev->dev_list, &atm_devs);
up(&atm_dev_mutex);
return dev;
}
......@@ -125,37 +124,22 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
void atm_dev_deregister(struct atm_dev *dev)
{
unsigned long warning_time;
BUG_ON(test_bit(ATM_DF_REMOVED, &dev->flags));
set_bit(ATM_DF_REMOVED, &dev->flags);
/*
* if we remove current device from atm_devs list, new device
* with same number can appear, such we need deregister proc,
* release async all vccs and remove them from vccs list too
*/
down(&atm_dev_mutex);
list_del(&dev->dev_list);
up(&atm_dev_mutex);
atm_dev_release_vccs(dev);
atm_proc_dev_deregister(dev);
spin_lock(&atm_dev_lock);
list_del(&dev->dev_list);
spin_unlock(&atm_dev_lock);
warning_time = jiffies;
while (atomic_read(&dev->refcnt) != 1) {
msleep(250);
if ((jiffies - warning_time) > 10 * HZ) {
printk(KERN_EMERG "atm_dev_deregister: waiting for "
"dev %d to become free. Usage count = %d\n",
dev->number, atomic_read(&dev->refcnt));
warning_time = jiffies;
}
}
kfree(dev);
}
void shutdown_atm_dev(struct atm_dev *dev)
{
if (atomic_read(&dev->refcnt) > 1) {
set_bit(ATM_DF_CLOSE, &dev->flags);
return;
}
if (dev->ops->dev_close)
dev->ops->dev_close(dev);
atm_dev_deregister(dev);
atm_dev_put(dev);
}
......@@ -211,16 +195,16 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg)
return -EFAULT;
if (get_user(len, &iobuf->length))
return -EFAULT;
spin_lock(&atm_dev_lock);
down(&atm_dev_mutex);
list_for_each(p, &atm_devs)
size += sizeof(int);
if (size > len) {
spin_unlock(&atm_dev_lock);
up(&atm_dev_mutex);
return -E2BIG;
}
tmp_buf = kmalloc(size, GFP_ATOMIC);
if (!tmp_buf) {
spin_unlock(&atm_dev_lock);
up(&atm_dev_mutex);
return -ENOMEM;
}
tmp_p = tmp_buf;
......@@ -228,7 +212,7 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg)
dev = list_entry(p, struct atm_dev, dev_list);
*tmp_p++ = dev->number;
}
spin_unlock(&atm_dev_lock);
up(&atm_dev_mutex);
error = ((copy_to_user(buf, tmp_buf, size)) ||
put_user(size, &iobuf->length))
? -EFAULT : 0;
......@@ -245,7 +229,8 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg)
if (get_user(number, &sioc->number))
return -EFAULT;
if (!(dev = atm_dev_lookup(number)))
if (!(dev = try_then_request_module(atm_dev_lookup(number),
"atm-device-%d", number)))
return -ENODEV;
switch (cmd) {
......@@ -414,13 +399,13 @@ static __inline__ void *dev_get_idx(loff_t left)
void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos)
{
spin_lock(&atm_dev_lock);
down(&atm_dev_mutex);
return *pos ? dev_get_idx(*pos) : (void *) 1;
}
void atm_dev_seq_stop(struct seq_file *seq, void *v)
{
spin_unlock(&atm_dev_lock);
up(&atm_dev_mutex);
}
void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
......@@ -434,4 +419,3 @@ void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
EXPORT_SYMBOL(atm_dev_register);
EXPORT_SYMBOL(atm_dev_deregister);
EXPORT_SYMBOL(atm_dev_lookup);
EXPORT_SYMBOL(shutdown_atm_dev);
......@@ -11,8 +11,7 @@
extern struct list_head atm_devs;
extern spinlock_t atm_dev_lock;
extern struct semaphore atm_dev_mutex;
int atm_dev_ioctl(unsigned int cmd, void __user *arg);
......
......@@ -975,7 +975,7 @@ static void fib_seq_stop(struct seq_file *seq, void *v)
static unsigned fib_flag_trans(int type, u32 mask, struct fib_info *fi)
{
static unsigned type2flags[RTN_MAX + 1] = {
static const unsigned type2flags[RTN_MAX + 1] = {
[7] = RTF_REJECT, [8] = RTF_REJECT,
};
unsigned flags = type2flags[type];
......
......@@ -83,7 +83,7 @@ for (nhsel=0; nhsel < 1; nhsel++)
#define endfor_nexthops(fi) }
static struct
static const struct
{
int error;
u8 scope;
......
......@@ -220,7 +220,7 @@ struct icmp_control {
short error; /* This ICMP is classed as an error message */
};
static struct icmp_control icmp_pointers[NR_ICMP_TYPES+1];
static const struct icmp_control icmp_pointers[NR_ICMP_TYPES+1];
/*
* The ICMP socket(s). This is the most convenient way to flow control
......@@ -994,7 +994,7 @@ int icmp_rcv(struct sk_buff *skb)
/*
* This table is the definition of how we handle ICMP.
*/
static struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = {
static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = {
[ICMP_ECHOREPLY] = {
.output_entry = ICMP_MIB_OUTECHOREPS,
.input_entry = ICMP_MIB_INECHOREPS,
......
......@@ -1217,7 +1217,7 @@ static int ipgre_tunnel_init(struct net_device *dev)
return 0;
}
int __init ipgre_fb_tunnel_init(struct net_device *dev)
static int __init ipgre_fb_tunnel_init(struct net_device *dev)
{
struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv;
struct iphdr *iph = &tunnel->parms.iph;
......
......@@ -690,7 +690,7 @@ csum_page(struct page *page, int offset, int copy)
return csum;
}
inline int ip_ufo_append_data(struct sock *sk,
static inline int ip_ufo_append_data(struct sock *sk,
int getfrag(void *from, char *to, int offset, int len,
int odd, struct sk_buff *skb),
void *from, int length, int hh_len, int fragheaderlen,
......
......@@ -771,7 +771,7 @@ static inline int todrop_entry(struct ip_vs_conn *cp)
* The drop rate array needs tuning for real environments.
* Called from timer bh only => no locking
*/
static char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
static const char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
static char todrop_counter[9] = {0};
int i;
......
......@@ -1909,7 +1909,7 @@ static int ip_vs_set_timeout(struct ip_vs_timeout_user *u)
#define DAEMON_ARG_LEN (sizeof(struct ip_vs_daemon_user))
#define MAX_ARG_LEN SVCDEST_ARG_LEN
static unsigned char set_arglen[SET_CMDID(IP_VS_SO_SET_MAX)+1] = {
static const unsigned char set_arglen[SET_CMDID(IP_VS_SO_SET_MAX)+1] = {
[SET_CMDID(IP_VS_SO_SET_ADD)] = SERVICE_ARG_LEN,
[SET_CMDID(IP_VS_SO_SET_EDIT)] = SERVICE_ARG_LEN,
[SET_CMDID(IP_VS_SO_SET_DEL)] = SERVICE_ARG_LEN,
......@@ -2180,7 +2180,7 @@ __ip_vs_get_timeouts(struct ip_vs_timeout_user *u)
#define GET_TIMEOUT_ARG_LEN (sizeof(struct ip_vs_timeout_user))
#define GET_DAEMON_ARG_LEN (sizeof(struct ip_vs_daemon_user) * 2)
static unsigned char get_arglen[GET_CMDID(IP_VS_SO_GET_MAX)+1] = {
static const unsigned char get_arglen[GET_CMDID(IP_VS_SO_GET_MAX)+1] = {
[GET_CMDID(IP_VS_SO_GET_VERSION)] = 64,
[GET_CMDID(IP_VS_SO_GET_INFO)] = GET_INFO_ARG_LEN,
[GET_CMDID(IP_VS_SO_GET_SERVICES)] = GET_SERVICES_ARG_LEN,
......
......@@ -251,7 +251,7 @@ tcp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp)
#define TCP_DIR_OUTPUT 4
#define TCP_DIR_INPUT_ONLY 8
static int tcp_state_off[IP_VS_DIR_LAST] = {
static const int tcp_state_off[IP_VS_DIR_LAST] = {
[IP_VS_DIR_INPUT] = TCP_DIR_INPUT,
[IP_VS_DIR_OUTPUT] = TCP_DIR_OUTPUT,
[IP_VS_DIR_INPUT_ONLY] = TCP_DIR_INPUT_ONLY,
......
......@@ -37,7 +37,7 @@ MODULE_LICENSE("GPL");
module_param(master_timeout, int, 0600);
MODULE_PARM_DESC(master_timeout, "timeout for the master connection");
static char *conns[] = { "DATA ", "MESG ", "INDEX " };
static const char *conns[] = { "DATA ", "MESG ", "INDEX " };
/* This is slow, but it's simple. --RR */
static char *amanda_buffer;
......
......@@ -1354,7 +1354,7 @@ static void free_conntrack_hash(struct list_head *hash, int vmalloced,int size)
get_order(sizeof(struct list_head) * size));
}
void ip_conntrack_flush()
void ip_conntrack_flush(void)
{
/* This makes sure all current packets have passed through
netfilter framework. Roll on, two-stage module
......@@ -1408,7 +1408,7 @@ static struct list_head *alloc_hashtable(int size, int *vmalloced)
return hash;
}
int set_hashsize(const char *val, struct kernel_param *kp)
static int set_hashsize(const char *val, struct kernel_param *kp)
{
int i, bucket, hashsize, vmalloced;
int old_vmalloced, old_size;
......
......@@ -55,7 +55,7 @@ static int try_rfc959(const char *, size_t, u_int32_t [], char);
static int try_eprt(const char *, size_t, u_int32_t [], char);
static int try_epsv_response(const char *, size_t, u_int32_t [], char);
static struct ftp_search {
static const struct ftp_search {
enum ip_conntrack_dir dir;
const char *pattern;
size_t plen;
......
......@@ -59,7 +59,7 @@ MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC
module_param(dcc_timeout, int, 0400);
MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels");
static char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " };
static const char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " };
#define MINMATCHLEN 5
#if 0
......
......@@ -51,7 +51,7 @@ static int icmp_invert_tuple(struct ip_conntrack_tuple *tuple,
const struct ip_conntrack_tuple *orig)
{
/* Add 1; spaces filled with 0. */
static u_int8_t invmap[]
static const u_int8_t invmap[]
= { [ICMP_ECHO] = ICMP_ECHOREPLY + 1,
[ICMP_ECHOREPLY] = ICMP_ECHO + 1,
[ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
......@@ -110,7 +110,7 @@ static int icmp_packet(struct ip_conntrack *ct,
return NF_ACCEPT;
}
static u_int8_t valid_new[] = {
static const u_int8_t valid_new[] = {
[ICMP_ECHO] = 1,
[ICMP_TIMESTAMP] = 1,
[ICMP_INFO_REQUEST] = 1,
......
......@@ -65,7 +65,7 @@ static unsigned long ip_ct_sctp_timeout_shutdown_sent = 300 SECS / 1000;
static unsigned long ip_ct_sctp_timeout_shutdown_recd = 300 SECS / 1000;
static unsigned long ip_ct_sctp_timeout_shutdown_ack_sent = 3 SECS;
static unsigned long * sctp_timeouts[]
static const unsigned long * sctp_timeouts[]
= { NULL, /* SCTP_CONNTRACK_NONE */
&ip_ct_sctp_timeout_closed, /* SCTP_CONNTRACK_CLOSED */
&ip_ct_sctp_timeout_cookie_wait, /* SCTP_CONNTRACK_COOKIE_WAIT */
......@@ -118,7 +118,7 @@ cookie echoed to closed.
*/
/* SCTP conntrack state transitions */
static enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
static const enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
{
/* ORIGINAL */
/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
......
......@@ -99,7 +99,7 @@ unsigned long ip_ct_tcp_timeout_close = 10 SECS;
to ~13-30min depending on RTO. */
unsigned long ip_ct_tcp_timeout_max_retrans = 5 MINS;
static unsigned long * tcp_timeouts[]
static const unsigned long * tcp_timeouts[]
= { NULL, /* TCP_CONNTRACK_NONE */
&ip_ct_tcp_timeout_syn_sent, /* TCP_CONNTRACK_SYN_SENT, */
&ip_ct_tcp_timeout_syn_recv, /* TCP_CONNTRACK_SYN_RECV, */
......@@ -170,7 +170,7 @@ enum tcp_bit_set {
* if they are invalid
* or we do not support the request (simultaneous open)
*/
static enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
static const enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
{
/* ORIGINAL */
/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
......@@ -817,7 +817,7 @@ void ip_conntrack_tcp_update(struct sk_buff *skb,
#define TH_CWR 0x80
/* table of valid flag combinations - ECE and CWR are always valid */
static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
static const u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
{
[TH_SYN] = 1,
[TH_SYN|TH_ACK] = 1,
......
......@@ -49,7 +49,7 @@ static unsigned int ip_nat_htable_size;
static struct list_head *bysource;
#define MAX_IP_NAT_PROTO 256
struct ip_nat_protocol *ip_nat_protos[MAX_IP_NAT_PROTO];
static struct ip_nat_protocol *ip_nat_protos[MAX_IP_NAT_PROTO];
static inline struct ip_nat_protocol *
__ip_nat_proto_find(u_int8_t protonum)
......
......@@ -1892,7 +1892,7 @@ static int ipt_get_matches(char *buffer, char **start, off_t offset, int length)
return pos;
}
static struct { char *name; get_info_t *get_info; } ipt_proc_entry[] =
static const struct { char *name; get_info_t *get_info; } ipt_proc_entry[] =
{ { "ip_tables_names", ipt_get_tables },
{ "ip_tables_targets", ipt_get_targets },
{ "ip_tables_matches", ipt_get_matches },
......
......@@ -197,7 +197,7 @@ static void dump_packet(const struct nf_loginfo *info,
}
case IPPROTO_ICMP: {
struct icmphdr _icmph, *ich;
static size_t required_len[NR_ICMP_TYPES+1]
static const size_t required_len[NR_ICMP_TYPES+1]
= { [ICMP_ECHOREPLY] = 4,
[ICMP_DEST_UNREACH]
= 8 + sizeof(struct iphdr),
......@@ -351,7 +351,7 @@ static void dump_packet(const struct nf_loginfo *info,
/* maxlen = 230+ 91 + 230 + 252 = 803 */
}
struct nf_loginfo default_loginfo = {
static struct nf_loginfo default_loginfo = {
.type = NF_LOG_TYPE_LOG,
.u = {
.log = {
......
......@@ -98,7 +98,7 @@ fold_field(void *mib[], int offt)
}
/* snmp items */
static struct snmp_mib snmp4_ipstats_list[] = {
static const struct snmp_mib snmp4_ipstats_list[] = {
SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INRECEIVES),
SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS),
SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS),
......@@ -119,7 +119,7 @@ static struct snmp_mib snmp4_ipstats_list[] = {
SNMP_MIB_SENTINEL
};
static struct snmp_mib snmp4_icmp_list[] = {
static const struct snmp_mib snmp4_icmp_list[] = {
SNMP_MIB_ITEM("InMsgs", ICMP_MIB_INMSGS),
SNMP_MIB_ITEM("InErrors", ICMP_MIB_INERRORS),
SNMP_MIB_ITEM("InDestUnreachs", ICMP_MIB_INDESTUNREACHS),
......@@ -149,7 +149,7 @@ static struct snmp_mib snmp4_icmp_list[] = {
SNMP_MIB_SENTINEL
};
static struct snmp_mib snmp4_tcp_list[] = {
static const struct snmp_mib snmp4_tcp_list[] = {
SNMP_MIB_ITEM("RtoAlgorithm", TCP_MIB_RTOALGORITHM),
SNMP_MIB_ITEM("RtoMin", TCP_MIB_RTOMIN),
SNMP_MIB_ITEM("RtoMax", TCP_MIB_RTOMAX),
......@@ -167,7 +167,7 @@ static struct snmp_mib snmp4_tcp_list[] = {
SNMP_MIB_SENTINEL
};
static struct snmp_mib snmp4_udp_list[] = {
static const struct snmp_mib snmp4_udp_list[] = {
SNMP_MIB_ITEM("InDatagrams", UDP_MIB_INDATAGRAMS),
SNMP_MIB_ITEM("NoPorts", UDP_MIB_NOPORTS),
SNMP_MIB_ITEM("InErrors", UDP_MIB_INERRORS),
......@@ -175,7 +175,7 @@ static struct snmp_mib snmp4_udp_list[] = {
SNMP_MIB_SENTINEL
};
static struct snmp_mib snmp4_net_list[] = {
static const struct snmp_mib snmp4_net_list[] = {
SNMP_MIB_ITEM("SyncookiesSent", LINUX_MIB_SYNCOOKIESSENT),
SNMP_MIB_ITEM("SyncookiesRecv", LINUX_MIB_SYNCOOKIESRECV),
SNMP_MIB_ITEM("SyncookiesFailed", LINUX_MIB_SYNCOOKIESFAILED),
......
......@@ -1371,7 +1371,7 @@ out: kfree_skb(skb);
* are needed for AMPRnet AX.25 paths.
*/
static unsigned short mtu_plateau[] =
static const unsigned short mtu_plateau[] =
{32000, 17914, 8166, 4352, 2002, 1492, 576, 296, 216, 128 };
static __inline__ unsigned short guess_mtu(unsigned short old_mtu)
......@@ -3149,8 +3149,7 @@ int __init ip_rt_init(void)
sizeof(struct rt_hash_bucket),
rhash_entries,
(num_physpages >= 128 * 1024) ?
(27 - PAGE_SHIFT) :
(29 - PAGE_SHIFT),
15 : 17,
HASH_HIGHMEM,
&rt_hash_log,
&rt_hash_mask,
......
......@@ -1413,7 +1413,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
* closed.
*/
static unsigned char new_state[16] = {
static const unsigned char new_state[16] = {
/* current state: new state: action: */
/* (Invalid) */ TCP_CLOSE,
/* TCP_ESTABLISHED */ TCP_FIN_WAIT1 | TCP_ACTION_FIN,
......@@ -2065,8 +2065,7 @@ void __init tcp_init(void)
sizeof(struct inet_ehash_bucket),
thash_entries,
(num_physpages >= 128 * 1024) ?
(25 - PAGE_SHIFT) :
(27 - PAGE_SHIFT),
13 : 15,
HASH_HIGHMEM,
&tcp_hashinfo.ehash_size,
NULL,
......@@ -2082,8 +2081,7 @@ void __init tcp_init(void)
sizeof(struct inet_bind_hashbucket),
tcp_hashinfo.ehash_size,
(num_physpages >= 128 * 1024) ?
(25 - PAGE_SHIFT) :
(27 - PAGE_SHIFT),
13 : 15,
HASH_HIGHMEM,
&tcp_hashinfo.bhash_size,
NULL,
......
......@@ -751,7 +751,7 @@ void icmpv6_cleanup(void)
inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
}
static struct icmp6_err {
static const struct icmp6_err {
int err;
int fatal;
} tab_unreach[] = {
......
......@@ -774,7 +774,8 @@ int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
*dst = NULL;
return err;
}
inline int ip6_ufo_append_data(struct sock *sk,
static inline int ip6_ufo_append_data(struct sock *sk,
int getfrag(void *from, char *to, int offset, int len,
int odd, struct sk_buff *skb),
void *from, int length, int hh_len, int fragheaderlen,
......
......@@ -628,8 +628,8 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
return -EINVAL;
}
int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr,
char __user *optval, int len)
static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr,
char __user *optval, int len)
{
if (!hdr)
return 0;
......
......@@ -1972,7 +1972,7 @@ static int ip6t_get_matches(char *buffer, char **start, off_t offset, int length
return pos;
}
static struct { char *name; get_info_t *get_info; } ip6t_proc_entry[] =
static const struct { char *name; get_info_t *get_info; } ip6t_proc_entry[] =
{ { "ip6_tables_names", ip6t_get_tables },
{ "ip6_tables_targets", ip6t_get_targets },
{ "ip6_tables_matches", ip6t_get_matches },
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册