Hi All,
Could you take a look at this patch for the atm reference counting and
locking problems? I think this will fix these problems. But I could
have missed someting. Please ignore the "firestream" parts. They are
for an other driver (which will come later).
Patrick
diff -u -r linux-2.4.0-test10-pre4.clean/drivers/atm/Config.in
linux-2.4.0-test10-pre4.fs50/drivers/atm/Config.in
--- linux-2.4.0-test10-pre4.clean/drivers/atm/Config.in Wed Jul 12 12:24:48 2000
+++ linux-2.4.0-test10-pre4.fs50/drivers/atm/Config.in Thu Oct 19 10:15:51 2000
@@ -22,6 +22,7 @@
bool ' Enable 2W RX bursts (optional)' CONFIG_ATM_ENI_BURST_RX_2W
fi
fi
+ tristate 'Fujitsu FireStream (FS50/FS155) ' CONFIG_ATM_FIRESTREAM
tristate 'ZeitNet ZN1221/ZN1225' CONFIG_ATM_ZATM
if [ "$CONFIG_ATM_ZATM" != "n" ]; then
bool ' Enable extended debugging' CONFIG_ATM_ZATM_DEBUG
diff -u -r linux-2.4.0-test10-pre4.clean/drivers/atm/Makefile
linux-2.4.0-test10-pre4.fs50/drivers/atm/Makefile
--- linux-2.4.0-test10-pre4.clean/drivers/atm/Makefile Sun Aug 6 20:23:40 2000
+++ linux-2.4.0-test10-pre4.fs50/drivers/atm/Makefile Thu Oct 19 10:15:51 2000
@@ -19,6 +19,14 @@
endif
endif
+ifeq ($(CONFIG_ATM_FIRESTREAM),y)
+O_OBJS += firestream.o
+else
+ ifeq ($(CONFIG_ATM_FIRESTREAM),m)
+ M_OBJS += firestream.o
+ endif
+endif
+
ifeq ($(CONFIG_ATM_ZATM),y)
O_OBJS += zatm.o
OX_OBJS += uPD98402.o
diff -u -r linux-2.4.0-test10-pre4.clean/drivers/atm/ambassador.c
linux-2.4.0-test10-pre4.fs50/drivers/atm/ambassador.c
--- linux-2.4.0-test10-pre4.clean/drivers/atm/ambassador.c Wed Jul 12 12:25:48
2000
+++ linux-2.4.0-test10-pre4.fs50/drivers/atm/ambassador.c Thu Oct 19 10:15:51
+2000
@@ -1251,15 +1251,10 @@
}
}
- // prevent module unload while sleeping (kmalloc/down)
- // doing this any earlier would complicate more error return paths
- MOD_INC_USE_COUNT;
-
// get space for our vcc stuff
vcc = kmalloc (sizeof(amb_vcc), GFP_KERNEL);
if (!vcc) {
PRINTK (KERN_ERR, "out of memory!");
- MOD_DEC_USE_COUNT;
return -ENOMEM;
}
atm_vcc->dev_data = (void *) vcc;
@@ -1425,7 +1420,6 @@
// say the VPI/VCI is free again
clear_bit(ATM_VF_ADDR,&atm_vcc->flags);
- MOD_DEC_USE_COUNT;
return;
}
@@ -1703,7 +1697,8 @@
close: amb_close,
send: amb_send,
sg_send: amb_sg_send,
- proc_read: amb_proc_read
+ proc_read: amb_proc_read,
+ owner: THIS_MODULE,
};
/********** housekeeping **********/
diff -u -r linux-2.4.0-test10-pre4.clean/drivers/atm/atmdev_init.c
linux-2.4.0-test10-pre4.fs50/drivers/atm/atmdev_init.c
--- linux-2.4.0-test10-pre4.clean/drivers/atm/atmdev_init.c Fri Apr 14 18:37:10
2000
+++ linux-2.4.0-test10-pre4.fs50/drivers/atm/atmdev_init.c Thu Oct 19 10:15:51
+2000
@@ -56,5 +56,8 @@
#ifdef CONFIG_ATM_FORE200E
devs += fore200e_detect();
#endif
+#ifdef CONFIG_ATM_FIRESTREAM
+ devs += fs_detect();
+#endif
return devs;
}
diff -u -r linux-2.4.0-test10-pre4.clean/drivers/atm/atmtcp.c
linux-2.4.0-test10-pre4.fs50/drivers/atm/atmtcp.c
--- linux-2.4.0-test10-pre4.clean/drivers/atm/atmtcp.c Wed Jul 12 12:24:48 2000
+++ linux-2.4.0-test10-pre4.fs50/drivers/atm/atmtcp.c Thu Oct 19 10:15:51 2000
@@ -109,7 +109,7 @@
static void atmtcp_v_dev_close(struct atm_dev *dev)
{
- MOD_DEC_USE_COUNT;
+ /* Nothing.... Isn't this simple :-) -- REW */
}
@@ -297,7 +297,8 @@
close: atmtcp_v_close,
ioctl: atmtcp_v_ioctl,
send: atmtcp_v_send,
- proc_read: atmtcp_v_proc
+ proc_read: atmtcp_v_proc,
+ owner: THIS_MODULE
};
@@ -330,18 +331,14 @@
struct atmtcp_dev_data *dev_data;
struct atm_dev *dev;
- MOD_INC_USE_COUNT;
-
dev_data = kmalloc(sizeof(*dev_data),GFP_KERNEL);
if (!dev_data) {
- MOD_DEC_USE_COUNT;
return -ENOMEM;
}
dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL);
if (!dev) {
kfree(dev_data);
- MOD_DEC_USE_COUNT;
return itf == -1 ? -ENOMEM : -EBUSY;
}
dev->ci_range.vpi_bits = MAX_VPI_BITS;
Only in linux-2.4.0-test10-pre4.fs50/drivers/atm: firestream.c
Only in linux-2.4.0-test10-pre4.fs50/drivers/atm: firestream.h
diff -u -r linux-2.4.0-test10-pre4.clean/drivers/atm/fore200e.c
linux-2.4.0-test10-pre4.fs50/drivers/atm/fore200e.c
--- linux-2.4.0-test10-pre4.clean/drivers/atm/fore200e.c Thu Oct 19 10:12:40
2000
+++ linux-2.4.0-test10-pre4.fs50/drivers/atm/fore200e.c Thu Oct 19 10:15:51 2000
@@ -1407,8 +1407,6 @@
struct fore200e* fore200e = FORE200E_DEV(vcc->dev);
struct fore200e_vcc* fore200e_vcc;
- MOD_INC_USE_COUNT;
-
/* find a free VPI/VCI */
fore200e_walk_vccs(vcc, &vpi, &vci);
@@ -1417,7 +1415,6 @@
/* ressource checking only? */
if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC) {
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -1437,7 +1434,6 @@
down(&fore200e->rate_sf);
if (fore200e->available_cell_rate < vcc->qos.txtp.max_pcr) {
up(&fore200e->rate_sf);
- MOD_DEC_USE_COUNT;
return -EAGAIN;
}
/* reserving the pseudo-CBR bandwidth at this point grants us
@@ -1454,7 +1450,6 @@
down(&fore200e->rate_sf);
fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
up(&fore200e->rate_sf);
- MOD_DEC_USE_COUNT;
return -ENOMEM;
}
@@ -1465,7 +1460,6 @@
down(&fore200e->rate_sf);
fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
up(&fore200e->rate_sf);
- MOD_DEC_USE_COUNT;
return -EBUSY;
}
@@ -1498,10 +1492,6 @@
fore200e_activate_vcin(fore200e, 0, vcc, 0);
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
-
kfree(FORE200E_VCC(vcc));
if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
@@ -2599,8 +2589,6 @@
printk(FORE200E "FORE Systems 200E-series driver - version " FORE200E_VERSION
"\n");
- MOD_INC_USE_COUNT;
-
/* for each configured bus interface */
for (link = 0, bus = fore200e_bus; bus->model_name; bus++) {
@@ -2626,9 +2614,6 @@
}
}
- if (link <= 0)
- MOD_DEC_USE_COUNT;
-
return link;
}
@@ -2943,21 +2928,15 @@
static const struct atmdev_ops fore200e_ops =
{
- NULL, /* fore200e_dev_close */
- fore200e_open,
- fore200e_close,
- fore200e_ioctl,
- fore200e_getsockopt,
- fore200e_setsockopt,
- fore200e_send,
- NULL, /* fore200e_sg_send, */
- NULL, /* fore200e_send_oam, */
- NULL, /* fore200e_phy_put, */
- NULL, /* fore200e_phy_get, */
- NULL, /* fore200e_feedback, */
- fore200e_change_qos,
- NULL, /* fore200e_free_rx_skb */
- fore200e_proc_read
+ open: fore200e_open,
+ close: fore200e_close,
+ ioctl: fore200e_ioctl,
+ getsockopt: fore200e_getsockopt,
+ setsockopt: fore200e_setsockopt,
+ send: fore200e_send,
+ change_qos: fore200e_change_qos,
+ proc_read: fore200e_proc_read,
+ owner: THIS_MODULE,
};
diff -u -r linux-2.4.0-test10-pre4.clean/drivers/atm/horizon.c
linux-2.4.0-test10-pre4.fs50/drivers/atm/horizon.c
--- linux-2.4.0-test10-pre4.clean/drivers/atm/horizon.c Wed Jul 12 12:25:48 2000
+++ linux-2.4.0-test10-pre4.fs50/drivers/atm/horizon.c Thu Oct 19 10:15:51 2000
@@ -2491,15 +2491,10 @@
return -EINVAL;
}
- // prevent module unload while sleeping (kmalloc)
- // doing this any earlier would complicate more error return paths
- MOD_INC_USE_COUNT;
-
// get space for our vcc stuff and copy parameters into it
vccp = kmalloc (sizeof(hrz_vcc), GFP_KERNEL);
if (!vccp) {
PRINTK (KERN_ERR, "out of memory!");
- MOD_DEC_USE_COUNT;
return -ENOMEM;
}
*vccp = vcc;
@@ -2531,7 +2526,6 @@
if (error) {
PRINTD (DBG_QOS|DBG_VCC, "insufficient cell rate resources");
kfree (vccp);
- MOD_DEC_USE_COUNT;
return error;
}
@@ -2550,7 +2544,6 @@
error = hrz_open_rx (dev, channel);
if (error) {
kfree (vccp);
- MOD_DEC_USE_COUNT;
return error;
}
// this link allows RX frames through
@@ -2620,7 +2613,6 @@
kfree (vcc);
// say the VPI/VCI is free again
clear_bit(ATM_VF_ADDR,&atm_vcc->flags);
- MOD_DEC_USE_COUNT;
}
#if 0
@@ -2751,7 +2743,8 @@
close: hrz_close,
send: hrz_send,
sg_send: hrz_sg_send,
- proc_read: hrz_proc_read
+ proc_read: hrz_proc_read,
+ owner: THIS_MODULE,
};
static int __init hrz_probe (void) {
diff -u -r linux-2.4.0-test10-pre4.clean/drivers/atm/iphase.c
linux-2.4.0-test10-pre4.fs50/drivers/atm/iphase.c
--- linux-2.4.0-test10-pre4.clean/drivers/atm/iphase.c Mon Aug 7 07:20:09 2000
+++ linux-2.4.0-test10-pre4.fs50/drivers/atm/iphase.c Thu Oct 19 10:15:51 2000
@@ -3143,7 +3143,8 @@
phy_put: ia_phy_put,
phy_get: ia_phy_get,
change_qos: ia_change_qos,
- proc_read: ia_proc_read
+ proc_read: ia_proc_read,
+ owner: THIS_MODULE,
};
@@ -3219,7 +3220,6 @@
printk(KERN_ERR DEV_LABEL ": no adapter found\n");
return -ENXIO;
}
- // MOD_INC_USE_COUNT;
ia_timer.expires = jiffies + 3*HZ;
add_timer(&ia_timer);
@@ -3235,7 +3235,6 @@
int i, j= 0;
IF_EVENT(printk(">ia cleanup_module\n");)
- // MOD_DEC_USE_COUNT;
if (MOD_IN_USE)
printk("ia: module in use\n");
del_timer(&ia_timer);
diff -u -r linux-2.4.0-test10-pre4.clean/drivers/atm/nicstar.c
linux-2.4.0-test10-pre4.fs50/drivers/atm/nicstar.c
--- linux-2.4.0-test10-pre4.clean/drivers/atm/nicstar.c Thu Oct 19 10:12:40 2000
+++ linux-2.4.0-test10-pre4.fs50/drivers/atm/nicstar.c Thu Oct 19 14:49:06 2000
@@ -268,7 +268,8 @@
send: ns_send,
phy_put: ns_phy_put,
phy_get: ns_phy_get,
- proc_read: ns_proc_read
+ proc_read: ns_proc_read,
+ owner: THIS_MODULE,
};
static struct timer_list ns_timer;
static char *mac[NS_MAX_CARDS] = { NULL
@@ -1649,7 +1650,6 @@
}
set_bit(ATM_VF_READY,&vcc->flags);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -1778,7 +1778,6 @@
vcc->dev_data = NULL;
clear_bit(ATM_VF_PARTIAL,&vcc->flags);
clear_bit(ATM_VF_ADDR,&vcc->flags);
- MOD_DEC_USE_COUNT;
#ifdef RX_DEBUG
{
diff -u -r linux-2.4.0-test10-pre4.clean/drivers/pci/pci.ids
linux-2.4.0-test10-pre4.fs50/drivers/pci/pci.ids
--- linux-2.4.0-test10-pre4.clean/drivers/pci/pci.ids Thu Oct 19 10:12:46 2000
+++ linux-2.4.0-test10-pre4.fs50/drivers/pci/pci.ids Thu Oct 19 10:15:51 2000
@@ -2438,7 +2438,9 @@
1221 82C092G
119c Information Technology Inst.
119d Bug, Inc. Sapporo Japan
-119e Fujitsu Microelectronics Ltd.
+119e Fujitsu Microelectronics Europe GMBH
+ 0001 FireStream 155
+ 0003 FireStream 50
119f Bull HN Information Systems
11a0 Convex Computer Corporation
11a1 Hamamatsu Photonics K.K.
diff -u -r linux-2.4.0-test10-pre4.clean/include/linux/atm_tcp.h
linux-2.4.0-test10-pre4.fs50/include/linux/atm_tcp.h
--- linux-2.4.0-test10-pre4.clean/include/linux/atm_tcp.h Wed Oct 18 16:27:29
2000
+++ linux-2.4.0-test10-pre4.fs50/include/linux/atm_tcp.h Thu Oct 19 10:19:43
+2000
@@ -65,6 +65,7 @@
int (*attach)(struct atm_vcc *vcc,int itf);
int (*create_persistent)(int itf);
int (*remove_persistent)(int itf);
+ struct module *owner;
};
extern struct atm_tcp_ops atm_tcp_ops;
diff -u -r linux-2.4.0-test10-pre4.clean/include/linux/atmdev.h
linux-2.4.0-test10-pre4.fs50/include/linux/atmdev.h
--- linux-2.4.0-test10-pre4.clean/include/linux/atmdev.h Wed Oct 18 16:27:23
2000
+++ linux-2.4.0-test10-pre4.fs50/include/linux/atmdev.h Thu Oct 19 10:19:43 2000
@@ -375,6 +375,7 @@
void (*free_rx_skb)(struct atm_vcc *vcc, struct sk_buff *skb);
/* @@@ temporary hack */
int (*proc_read)(struct atm_dev *dev,loff_t *pos,char *page);
+ struct module *owner;
};
diff -u -r linux-2.4.0-test10-pre4.clean/include/linux/pci_ids.h
linux-2.4.0-test10-pre4.fs50/include/linux/pci_ids.h
--- linux-2.4.0-test10-pre4.clean/include/linux/pci_ids.h Thu Oct 19 10:12:57
2000
+++ linux-2.4.0-test10-pre4.fs50/include/linux/pci_ids.h Thu Oct 19 10:15:51
+2000
@@ -868,6 +868,10 @@
#define PCI_VENDOR_ID_OMEGA 0x119b
#define PCI_DEVICE_ID_OMEGA_82C092G 0x1221
+#define PCI_VENDOR_ID_FUJITSU_ME 0x119e
+#define PCI_DEVICE_ID_FUJITSU_FS155 0x0001
+#define PCI_DEVICE_ID_FUJITSU_FS50 0x0003
+
#define PCI_SUBVENDOR_ID_KEYSPAN 0x11a9
#define PCI_SUBDEVICE_ID_KEYSPAN_SX2 0x5334
Only in linux-2.4.0-test10-pre4.fs50/net/atm: #resources.c#
Only in linux-2.4.0-test10-pre4.fs50/net/atm: .#resources.c
diff -u -r linux-2.4.0-test10-pre4.clean/net/atm/common.c
linux-2.4.0-test10-pre4.fs50/net/atm/common.c
--- linux-2.4.0-test10-pre4.clean/net/atm/common.c Wed Jul 12 12:26:08 2000
+++ linux-2.4.0-test10-pre4.fs50/net/atm/common.c Thu Oct 19 14:42:11 2000
@@ -72,6 +72,7 @@
#define DPRINTK(format,args...)
#endif
+static spinlock_t atm_dev_lock = SPIN_LOCK_UNLOCKED;
static struct sk_buff *alloc_tx(struct atm_vcc *vcc,unsigned int size)
{
@@ -139,6 +140,7 @@
vcc->dev->ops->free_rx_skb(vcc,skb);
else kfree_skb(skb);
}
+ fops_put (vcc->dev->ops);
if (atomic_read(&vcc->rx_inuse))
printk(KERN_WARNING "atm_release_vcc: strange ... "
"rx_inuse == %d after closing\n",
@@ -238,9 +240,11 @@
vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu);
DPRINTK(" RX: %d, PCR %d..%d, SDU %d\n",vcc->qos.rxtp.traffic_class,
vcc->qos.rxtp.min_pcr,vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu);
+ fops_get (dev->ops);
if (dev->ops->open) {
error = dev->ops->open(vcc,vpi,vci);
if (error) {
+ fops_put (dev->ops);
bind_vcc(vcc,NULL);
return error;
}
@@ -252,13 +256,26 @@
static int atm_do_connect(struct atm_vcc *vcc,int itf,int vpi,int vci)
{
struct atm_dev *dev;
+ int return_val;
+ printk ("lock %s\n", __FUNCTION__);
+ spin_lock (&atm_dev_lock);
+ printk ("Before find device\n");
dev = atm_find_dev(itf);
- if (!dev) return -ENODEV;
- return atm_do_connect_dev(vcc,dev,vpi,vci);
+ printk ("After find device\n");
+ if (!dev){
+ spin_unlock (&atm_dev_lock);
+ printk ("spin unlock\n");
+ return -ENODEV;
+ }
+ return_val = atm_do_connect_dev(vcc,dev,vpi,vci);
+ spin_unlock (&atm_dev_lock);
+ printk("unlock\n");
+ return return_val;
}
+
int atm_connect_vcc(struct atm_vcc *vcc,int itf,short vpi,int vci)
{
if (vpi != ATM_VPI_UNSPEC && vci != ATM_VCI_UNSPEC)
@@ -284,9 +301,14 @@
}
else {
struct atm_dev *dev;
-
+ printk ("lock atm_connect_vcc\n");
+ spin_lock (&atm_dev_lock);
for (dev = atm_devs; dev; dev = dev->next)
- if (!atm_do_connect_dev(vcc,dev,vpi,vci)) break;
+ if (!atm_do_connect_dev(vcc,dev,vpi,vci)){
+ break;
+ }
+ spin_unlock (&atm_dev_lock);
+ printk ("unlock atm_connect_vcc\n");
if (!dev) return -ENODEV;
}
if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC)
@@ -552,13 +574,21 @@
&((struct atm_iobuf *) arg)->length))
return -EFAULT;
size = 0;
+ printk("spin lock %s\n", __FUNCTION__);
+ spin_lock (&atm_dev_lock);
for (dev = atm_devs; dev; dev = dev->next)
size += sizeof(int);
+ spin_unlock (&atm_dev_lock);
+ printk ("spin unlock\n");
if (size > len) return -E2BIG;
tmp_buf = kmalloc(size,GFP_KERNEL);
if (!tmp_buf) return -ENOMEM;
+ printk("spin lock %s\n", __FUNCTION__);
+ spin_lock (&atm_dev_lock);
for (dev = atm_devs; dev; dev = dev->next)
*tmp_buf++ = dev->number;
+ spin_unlock (&atm_dev_lock);
+ printk("spin unlock\n");
if (copy_to_user(buf,(char *) tmp_buf-size,size))
return -EFAULT;
return put_user(size,
@@ -639,17 +669,23 @@
case SIOCSIFATMTCP:
if (!capable(CAP_NET_ADMIN)) return -EPERM;
if (!atm_tcp_ops.attach) return -ENOPKG;
+ fops_get (&atm_tcp_ops);
error = atm_tcp_ops.attach(vcc,(int) arg);
if (error >= 0) sock->state = SS_CONNECTED;
+ else fops_put (&atm_tcp_ops);
return error;
case ATMTCP_CREATE:
if (!capable(CAP_NET_ADMIN)) return -EPERM;
if (!atm_tcp_ops.create_persistent) return -ENOPKG;
- return atm_tcp_ops.create_persistent((int) arg);
+ error = atm_tcp_ops.create_persistent((int) arg);
+ if (error < 0) fops_put (&atm_tcp_ops);
+ return error;
case ATMTCP_REMOVE:
if (!capable(CAP_NET_ADMIN)) return -EPERM;
if (!atm_tcp_ops.remove_persistent) return -ENOPKG;
- return atm_tcp_ops.remove_persistent((int) arg);
+ error = atm_tcp_ops.remove_persistent((int) arg);
+ fops_put (&atm_tcp_ops);
+ return error;
#endif
default:
break;
@@ -658,7 +694,16 @@
if (get_user(len,&((struct atmif_sioc *) arg)->length)) return -EFAULT;
if (get_user(number,&((struct atmif_sioc *) arg)->number))
return -EFAULT;
- if (!(dev = atm_find_dev(number))) return -ENODEV;
+ printk("spin lock %s\n", __FUNCTION__);
+ spin_lock (&atm_dev_lock);
+ if (!(dev = atm_find_dev(number))) {
+ spin_unlock (&atm_dev_lock);
+ printk ("spin unlock\n");
+ return -ENODEV;
+ }
+ spin_unlock (&atm_dev_lock);
+ printk ("spin unlock\n");
+
size = 0;
switch (cmd) {
case ATM_GETTYPE:
----- End of forwarded message from Patrick van de Lageweg -----
--
** [EMAIL PROTECTED] ** http://www.BitWizard.nl/ ** +31-15-2137555 **
*-- BitWizard writes Linux device drivers for any device you may have! --*
* Common sense is the collection of *
****** prejudices acquired by age eighteen. -- Albert Einstein ********
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/