patch-1.3.86 linux/drivers/net/dlci.c
Next file: linux/drivers/net/eepro.c
Previous file: linux/drivers/net/Makefile
Back to the patch index
Back to the overall index
- Lines: 241
- Date:
Tue Apr 9 14:36:30 1996
- Orig file:
v1.3.85/linux/drivers/net/dlci.c
- Orig date:
Mon Mar 25 10:06:39 1996
diff -u --recursive --new-file v1.3.85/linux/drivers/net/dlci.c linux/drivers/net/dlci.c
@@ -5,7 +5,7 @@
* interfaces. Requires 'dlcicfg' program to create usable
* interfaces, the initial one, 'dlci' is for IOCTL use only.
*
- * Version: @(#)dlci.c 0.10 23 Mar 1996
+ * Version: @(#)dlci.c 0.15 31 Mar 1996
*
* Author: Mike McLagan <mike.mclagan@linux.org>
*
@@ -41,7 +41,7 @@
#include <net/sock.h>
static const char *devname = "dlci";
-static const char *version = "DLCI driver v0.10, 23 Mar 1996, mike.mclagan@linux.org";
+static const char *version = "DLCI driver v0.15, 31 Mar 1996, mike.mclagan@linux.org";
static struct device *open_dev[CONFIG_DLCI_COUNT];
@@ -68,9 +68,13 @@
}
if (i == sizeof(basename) / sizeof(char *))
+ return(-EMLINK);
+
+ basename[i] = kmalloc(strlen(name) + 1, GFP_KERNEL);
+ if (!basename[i])
return(-ENOMEM);
- basename[i] = (char *) name;
+ strcpy(basename[i], name);
return(0);
}
@@ -89,22 +93,23 @@
if (i == sizeof(basename) / sizeof(char *))
return(-EINVAL);
+ kfree(basename[i]);
basename[i] = NULL;
return(0);
}
/*
- these encapsulate the RFC 1490 requirements as well as
- deal with packet transmission and reception, working with
- the upper network layers
+ * these encapsulate the RFC 1490 requirements as well as
+ * deal with packet transmission and reception, working with
+ * the upper network layers
*/
static int dlci_header(struct sk_buff *skb, struct device *dev,
unsigned short type, void *daddr, void *saddr,
unsigned len)
{
- struct fradhdr hdr;
+ struct frhdr hdr;
struct dlci_local *dlp;
unsigned hlen;
char *dest;
@@ -115,8 +120,8 @@
switch(type)
{
case ETH_P_IP:
- hdr.pad = FRAD_P_IP;
- hlen = sizeof(hdr.control) + sizeof(hdr.pad);
+ hdr.IP_NLPID = FRAD_P_IP;
+ hlen = sizeof(hdr.control) + sizeof(hdr.IP_NLPID);
break;
/* feel free to add other types, if necessary */
@@ -142,11 +147,11 @@
static void dlci_receive(struct sk_buff *skb, struct device *dev)
{
struct dlci_local *dlp;
- struct fradhdr *hdr;
+ struct frhdr *hdr;
int process, header;
dlp = dev->priv;
- hdr = (struct fradhdr *) skb->data;
+ hdr = (struct frhdr *) skb->data;
process = 0;
header = 0;
skb->dev = dev;
@@ -157,7 +162,7 @@
dlp->stats.rx_errors++;
}
else
- switch(hdr->pad)
+ switch(hdr->IP_NLPID)
{
case FRAD_P_PADDING:
if (hdr->NLPID != FRAD_P_SNAP)
@@ -175,13 +180,13 @@
}
/* at this point, it's an EtherType frame */
- header = sizeof(struct fradhdr);
+ header = sizeof(struct frhdr);
skb->protocol = htons(hdr->PID);
process = 1;
break;
case FRAD_P_IP:
- header = sizeof(hdr->control) + sizeof(hdr->pad);
+ header = sizeof(hdr->control) + sizeof(hdr->IP_NLPID);
skb->protocol = htons(ETH_P_IP);
process = 1;
break;
@@ -230,14 +235,25 @@
printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name);
else
{
- ret = dlp->slave->hard_start_xmit(skb, dlp->slave);
- if (ret)
- dlp->stats.tx_errors++;
- else
- dlp->stats.tx_packets++;
+ ret = dlp->slave->hard_start_xmit(skb, dlp->slave);
+ switch (ret)
+ {
+ case DLCI_RET_OK:
+ dlp->stats.tx_packets++;
+ break;
- /* per Alan Cox, always return 0, let the slave free the packet */
+ case DLCI_RET_ERR:
+ dlp->stats.tx_errors++;
+ break;
+
+ case DLCI_RET_DROP:
+ dlp->stats.tx_dropped++;
+ break;
+ }
+
+ /* Alan Cox recommends always returning 0, and always freeing the packet */
ret = 0;
+ dev_kfree_skb(skb, FREE_WRITE);
dev->tbusy = 0;
}
@@ -257,6 +273,10 @@
if (err)
return(err);
+ err = verify_area(VERIFY_WRITE, new, sizeof(*new));
+ if (err)
+ return(err);
+
memcpy_fromfs(&dlci, new, sizeof(dlci));
/* validate slave device */
@@ -293,7 +313,7 @@
return(-ENOMEM);
memset(master, 0, sizeof(*master));
- master->name = kmalloc(strlen(buf), GFP_KERNEL);
+ master->name = kmalloc(strlen(buf) + 1, GFP_KERNEL);
if (!master->name)
{
@@ -502,6 +522,7 @@
err = (*flp->deactivate)(dlp->slave, dev);
dev->start = 0;
+ dev->tbusy = 1;
return 0;
}
@@ -540,14 +561,25 @@
dev->type = ARPHRD_DLCI;
dev->family = AF_INET;
- dev->hard_header_len = sizeof(struct fradhdr);
+ dev->hard_header_len = sizeof(struct frhdr);
dev->pa_alen = sizeof(unsigned long);
-
+ dev->addr_len = sizeof(short);
memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
+ dev->pa_addr = 0;
+ dev->pa_dstaddr = 0;
+ dev->pa_brdaddr = 0;
+ dev->pa_mask = 0;
+
for (i = 0; i < DEV_NUMBUFFS; i++)
skb_queue_head_init(&dev->buffs[i]);
+ if (strcmp(dev->name, devname) == 0)
+ {
+ dev->type = 0xFFFF;
+ dev->family = AF_UNSPEC;
+ }
+
return(0);
}
@@ -567,7 +599,7 @@
}
#ifdef MODULE
-static struct device dlci = {"dlci", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, dlci_init, };
+static struct device dlci = {devname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, dlci_init, };
int init_module(void)
{
@@ -577,32 +609,7 @@
void cleanup_module(void)
{
- struct dlci_local *dlp;
- struct frad_local *flp;
- int i;
-
unregister_netdev(&dlci);
-
- for(i=0;i<CONFIG_DLCI_COUNT;i++)
- if (open_dev[i])
- {
- dlp = open_dev[i]->priv;
- flp = open_dev[i]->slave->priv;
-
- if (open_dev[i]->start)
- {
- if (flp->deactivate)
- (*flp->deactivate)(open_dev[i]->slave, open_dev[i]);
- open_dev[i]->start = 0;
- }
-
- (*flp->deassoc)(open_dev[i]->slave, open_dev[i]);
- kfree(open_dev[i]->priv);
- kfree(open_dev[i]->name);
- kfree(open_dev[i]);
- open_dev[i] = NULL;
- }
-
if (dlci.priv)
kfree(dlci.priv);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this