patch-2.3.14 linux/drivers/net/cycx_x25.c
Next file: linux/drivers/net/daynaport.c
Previous file: linux/drivers/net/cycx_main.c
Back to the patch index
Back to the overall index
- Lines: 860
- Date:
Wed Aug 18 11:36:41 1999
- Orig file:
v2.3.13/linux/drivers/net/cycx_x25.c
- Orig date:
Wed Jun 2 14:40:22 1999
diff -u --recursive --new-file v2.3.13/linux/drivers/net/cycx_x25.c linux/drivers/net/cycx_x25.c
@@ -11,6 +11,10 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
* ============================================================================
+* 1999/08/10 acme serialized access to the card thru a spinlock
+* in x25_exec
+* 1999/08/09 acme removed per channel spinlocks
+* removed references to enable_tx_int
* 1999/05/28 acme fixed nibble_to_byte, ackvc now properly treated
* if_send simplified
* 1999/05/25 acme fixed t1, t2, t21 & t23 configuration
@@ -70,11 +74,9 @@
/* Defines & Macros */
#define MAX_CMD_RETRY 5
#define X25_CHAN_MTU 2048 /* unfragmented logical channel MTU */
-#define OUT_INTR 1
-#define IN_INTR 0
/* Data Structures */
-/* This is an extention of the 'struct device' we create for each network
+/* This is an extention of the 'struct net_device' we create for each network
interface to keep the rest of X.25 channel-specific data. */
typedef struct x25_channel {
char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
@@ -84,7 +86,6 @@
s16 lcn; /* logical channel number/conn.req.key*/
u8 link;
struct timer_list timer; /* timer used for svc channel disc. */
- spinlock_t lock;
u16 protocol; /* ethertype, 0 - multiplexed */
u8 svc; /* 0 - permanent, 1 - switched */
u8 state; /* channel state */
@@ -98,19 +99,19 @@
/* Function Prototypes */
/* WAN link driver entry points. These are called by the WAN router module. */
static int update (wan_device_t *wandev),
- new_if (wan_device_t *wandev, struct device *dev,wanif_conf_t *conf),
- del_if (wan_device_t *wandev, struct device *dev);
+ new_if (wan_device_t *wandev, struct net_device *dev,wanif_conf_t *conf),
+ del_if (wan_device_t *wandev, struct net_device *dev);
/* Network device interface */
-static int if_init (struct device *dev),
- if_open (struct device *dev),
- if_close (struct device *dev),
- if_header (struct sk_buff *skb, struct device *dev,
+static int if_init (struct net_device *dev),
+ if_open (struct net_device *dev),
+ if_close (struct net_device *dev),
+ if_header (struct sk_buff *skb, struct net_device *dev,
u16 type, void *daddr, void *saddr, unsigned len),
if_rebuild_hdr (struct sk_buff *skb),
- if_send (struct sk_buff *skb, struct device *dev);
+ if_send (struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats * if_stats (struct device *dev);
+static struct net_device_stats * if_stats (struct net_device *dev);
/* Interrupt handlers */
static void cyx_isr (cycx_t *card),
@@ -132,22 +133,22 @@
x25_disconnect_response (cycx_t *card, u8 link, u8 lcn);
/* Miscellaneous functions */
-static int chan_connect (struct device *dev),
- chan_send (struct device *dev, struct sk_buff *skb);
+static int chan_connect (struct net_device *dev),
+ chan_send (struct net_device *dev, struct sk_buff *skb);
-static void set_chan_state (struct device *dev, u8 state, u8 outside_intr),
+static void set_chan_state (struct net_device *dev, u8 state),
nibble_to_byte (u8 *s, u8 *d, u8 len, u8 nibble),
- reset_timer (struct device *dev),
- chan_disc (struct device *dev),
- chan_timer (unsigned long data);
+ reset_timer (struct net_device *dev),
+ chan_disc (struct net_device *dev),
+ chan_timer (unsigned long d);
static u8 bps_to_speed_code (u32 bps);
static u8 log2 (u32 n);
static unsigned dec_to_uint (u8 *str, int len);
-static struct device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn);
-static struct device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte);
+static struct net_device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn);
+static struct net_device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte);
#ifdef CYCLOMX_X25_DEBUG
static void hex_dump(char *msg, unsigned char *p, int len);
@@ -187,8 +188,8 @@
/* Initialize protocol-specific fields */
card->mbox = card->hw.dpmbase + X25_MBOX_OFFS;
- card->u.x.critical = 0; /* critical section flag */
card->u.x.connection_keys = 0;
+ card->u.x.lock = SPIN_LOCK_UNLOCKED;
/* Configure adapter. Here we set resonable defaults, then parse
* device configuration structure and set configuration options.
@@ -286,7 +287,6 @@
card->wandev.new_if = &new_if;
card->wandev.del_if = &del_if;
card->wandev.state = WAN_DISCONNECTED;
- card->wandev.enable_tx_int = card->irq_dis_if_send_count = 0;
return 0;
}
@@ -315,7 +315,7 @@
*
* Return: 0 o.k.
* < 0 failure (channel will not be created) */
-static int new_if (wan_device_t *wandev, struct device *dev, wanif_conf_t *conf)
+static int new_if (wan_device_t *wandev, struct net_device *dev, wanif_conf_t *conf)
{
cycx_t *card = wandev->private;
x25_channel_t *chan;
@@ -338,21 +338,23 @@
chan->rx_skb = NULL;
/* only used in svc connected thru crossover cable */
chan->local_addr = NULL;
- chan->lock = SPIN_LOCK_UNLOCKED;
if (conf->addr[0] == '@') { /* SVC */
- int local_len = strlen(conf->local_addr);
+ int len = strlen(conf->local_addr);
- if (local_len) {
- if (local_len > WAN_ADDRESS_SZ) {
+ if (len) {
+ if (len > WAN_ADDRESS_SZ) {
printk(KERN_ERR "%s: %s local addr too long!\n",
wandev->name, chan->name);
kfree(chan);
return -EINVAL;
- } else if ((chan->local_addr = kmalloc(local_len + 1,
- GFP_KERNEL)) == NULL) {
- kfree(chan);
- return ENOMEM;
+ } else {
+ chan->local_addr = kmalloc(len + 1, GFP_KERNEL);
+
+ if (!chan->local_addr) {
+ kfree(chan);
+ return ENOMEM;
+ }
}
strncpy(chan->local_addr, conf->local_addr,
@@ -387,6 +389,7 @@
if (err) {
if (chan->local_addr)
kfree(chan->local_addr);
+
kfree(chan);
return err;
}
@@ -399,7 +402,7 @@
}
/* Delete logical channel. */
-static int del_if (wan_device_t *wandev, struct device *dev)
+static int del_if (wan_device_t *wandev, struct net_device *dev)
{
if (!dev) {
printk(KERN_ERR "cycx_x25:del_if:dev == NULL!\n");
@@ -408,6 +411,7 @@
if (dev->priv) {
x25_channel_t *chan = dev->priv;
+
if (chan->svc) {
if (chan->local_addr)
kfree(chan->local_addr);
@@ -415,6 +419,7 @@
if (chan->state == WAN_CONNECTED)
del_timer(&chan->timer);
}
+
kfree(chan);
dev->priv = NULL;
}
@@ -428,7 +433,7 @@
* This routine is called only once for each interface, during Linux network
* interface registration. Returning anything but zero will fail interface
* registration. */
-static int if_init (struct device *dev)
+static int if_init (struct net_device *dev)
{
x25_channel_t *chan = dev->priv;
cycx_t *card = chan->card;
@@ -464,7 +469,7 @@
/* Initialize socket buffers */
dev_init_buffers(dev);
- set_chan_state(dev, WAN_DISCONNECTED, OUT_INTR);
+ set_chan_state(dev, WAN_DISCONNECTED);
return 0;
}
@@ -473,7 +478,7 @@
* o if link is disconnected then initiate connection
*
* Return 0 if O.k. or errno. */
-static int if_open (struct device *dev)
+static int if_open (struct net_device *dev)
{
x25_channel_t *chan = dev->priv;
cycx_t *card = chan->card;
@@ -481,37 +486,28 @@
if (dev->start)
return -EBUSY; /* only one open is allowed */
- if (test_and_set_bit(0, (void*)&card->wandev.critical))
- return -EAGAIN;
-
dev->interrupt = 0;
dev->tbusy = 0;
dev->start = 1;
cyclomx_open(card);
- card->wandev.critical = 0;
return 0;
}
/* Close network interface.
* o reset flags.
* o if there's no more open channels then disconnect physical link. */
-static int if_close (struct device *dev)
+static int if_close (struct net_device *dev)
{
x25_channel_t *chan = dev->priv;
cycx_t *card = chan->card;
- if (test_and_set_bit(0, (void*)&card->wandev.critical))
- return -EAGAIN;
-
dev->start = 0;
if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING)
chan_disc(dev);
cyclomx_close(card);
-
- card->wandev.critical = 0;
return 0;
}
@@ -523,7 +519,7 @@
* set skb->protocol to 0 and discard packet later.
*
* Return: media header length. */
-static int if_header (struct sk_buff *skb, struct device *dev,
+static int if_header (struct sk_buff *skb, struct net_device *dev,
u16 type, void *daddr, void *saddr, unsigned len)
{
skb->protocol = type;
@@ -553,7 +549,7 @@
* bottom half" (with interrupts enabled).
* 2. Setting tbusy flag will inhibit further transmit requests from the
* protocol stack and can be used for flow control with protocol layer. */
-static int if_send (struct sk_buff *skb, struct device *dev)
+static int if_send (struct sk_buff *skb, struct net_device *dev)
{
x25_channel_t *chan = dev->priv;
cycx_t *card = chan->card;
@@ -563,10 +559,6 @@
return -EBUSY;
}
- dev->tbusy = 1;
-
- reset_timer(dev);
-
if (!chan->svc)
chan->protocol = skb->protocol;
@@ -580,13 +572,17 @@
++chan->ifstats.tx_errors;
} else switch (chan->state) {
case WAN_DISCONNECTED:
- if (chan_connect(dev))
+ if (chan_connect(dev)) {
+ dev->tbusy = 1;
return -EBUSY;
+ }
/* fall thru */
case WAN_CONNECTED:
+ reset_timer(dev);
dev->trans_start = jiffies;
+ dev->tbusy = 1;
+
if (chan_send(dev, skb)) {
- dev->tbusy = 1;
return -EBUSY;
}
break;
@@ -601,7 +597,7 @@
/* Get Ethernet-style interface statistics.
* Return a pointer to struct net_device_stats */
-static struct net_device_stats *if_stats (struct device *dev)
+static struct net_device_stats *if_stats (struct net_device *dev)
{
x25_channel_t *chan = dev->priv;
@@ -612,25 +608,13 @@
/* X.25 Interrupt Service Routine. */
static void cyx_isr (cycx_t *card)
{
- unsigned long host_cpu_flags;
TX25Cmd cmd;
u16 z = 0;
card->in_isr = 1;
card->buff_int_mode_unbusy = 0;
-
- if (test_and_set_bit(0, (void*)&card->wandev.critical)) {
- printk(KERN_INFO "cyx_isr: %s, wandev.critical set to 0x%02X\n",
- card->devname, card->wandev.critical);
- card->in_isr = 0;
- return;
- }
-
- /* For all interrupts set the critical flag to CRITICAL_RX_INTR.
- * If the if_send routine is called with this flag set it will set
- * the enable transmit flag to 1. (for a delayed interrupt) */
- card->wandev.critical = CRITICAL_IN_ISR;
cycx_peek(&card->hw, X25_RXMBOX_OFFS, &cmd, sizeof(cmd));
+
switch (cmd.command) {
case X25_DATA_INDICATION:
rx_intr(card, &cmd);
@@ -668,16 +652,7 @@
cycx_poke(&card->hw, 0, &z, sizeof(z));
cycx_poke(&card->hw, X25_RXMBOX_OFFS, &z, sizeof(z));
-
- card->wandev.critical = CRITICAL_INTR_HANDLED;
-
- if (card->wandev.enable_tx_int)
- card->wandev.enable_tx_int = 0;
-
- spin_lock_irqsave(&card->lock, host_cpu_flags);
card->in_isr = 0;
- card->wandev.critical = 0;
- spin_unlock_irqrestore(&card->lock, host_cpu_flags);
if (card->buff_int_mode_unbusy)
mark_bh(NET_BH);
@@ -688,7 +663,7 @@
* o Clear 'tbusy' flag */
static void tx_intr (cycx_t *card, TX25Cmd *cmd)
{
- struct device *dev;
+ struct net_device *dev;
wan_device_t *wandev = &card->wandev;
u8 lcn;
@@ -720,7 +695,7 @@
static void rx_intr (cycx_t *card, TX25Cmd *cmd)
{
wan_device_t *wandev = &card->wandev;
- struct device *dev;
+ struct net_device *dev;
x25_channel_t *chan;
struct sk_buff *skb;
u8 bitm, lcn;
@@ -740,11 +715,12 @@
chan = dev->priv;
reset_timer(dev);
- if (chan->drop_sequence)
+ if (chan->drop_sequence) {
if (!bitm)
chan->drop_sequence = 0;
else
return;
+ }
if ((skb = chan->rx_skb) == NULL) {
/* Allocate new socket buffer */
@@ -799,29 +775,30 @@
static void connect_intr (cycx_t *card, TX25Cmd *cmd)
{
wan_device_t *wandev = &card->wandev;
- struct device *dev = NULL;
+ struct net_device *dev = NULL;
x25_channel_t *chan;
- u8 data[32],
- local[24],
+ u8 d[32],
+ loc[24],
rem[24];
- u8 lcn, sizelocal, sizerem;
+ u8 lcn, sizeloc, sizerem;
cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
- cycx_peek(&card->hw, cmd->buf + 5, &sizelocal, sizeof(sizelocal));
- cycx_peek(&card->hw, cmd->buf + 6, data, cmd->len - 6);
+ cycx_peek(&card->hw, cmd->buf + 5, &sizeloc, sizeof(sizeloc));
+ cycx_peek(&card->hw, cmd->buf + 6, d, cmd->len - 6);
- sizerem = sizelocal >> 4;
- sizelocal &= 0x0F;
+ sizerem = sizeloc >> 4;
+ sizeloc &= 0x0F;
- local[0] = rem[0] = '\0';
+ loc[0] = rem[0] = '\0';
- if (sizelocal)
- nibble_to_byte(data, local, sizelocal, 0);
+ if (sizeloc)
+ nibble_to_byte(d, loc, sizeloc, 0);
if (sizerem)
- nibble_to_byte(data + (sizelocal >> 1), rem, sizerem, sizelocal & 1);
+ nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1);
+
dprintk(KERN_INFO "connect_intr:lcn=%d, local=%s, remote=%s\n",
- lcn, local, rem);
+ lcn, loc, rem);
if ((dev = get_dev_by_dte_addr(wandev, rem)) == NULL) {
/* Invalid channel, discard packet */
printk(KERN_INFO "%s: connect not expected: remote %s!\n",
@@ -832,14 +809,14 @@
chan = dev->priv;
chan->lcn = lcn;
x25_connect_response(card, chan);
- set_chan_state(dev, WAN_CONNECTED, IN_INTR);
+ set_chan_state(dev, WAN_CONNECTED);
}
/* Connect confirm interrupt handler. */
static void connect_confirm_intr (cycx_t *card, TX25Cmd *cmd)
{
wan_device_t *wandev = &card->wandev;
- struct device *dev;
+ struct net_device *dev;
x25_channel_t *chan;
u8 lcn, key;
@@ -858,14 +835,14 @@
clear_bit(--key, (void*)&card->u.x.connection_keys);
chan = dev->priv;
chan->lcn = lcn;
- set_chan_state(dev, WAN_CONNECTED, IN_INTR);
+ set_chan_state(dev, WAN_CONNECTED);
}
/* Disonnect confirm interrupt handler. */
static void disconnect_confirm_intr (cycx_t *card, TX25Cmd *cmd)
{
wan_device_t *wandev = &card->wandev;
- struct device *dev;
+ struct net_device *dev;
u8 lcn;
cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
@@ -878,22 +855,26 @@
return;
}
- set_chan_state(dev, WAN_DISCONNECTED, IN_INTR);
+ set_chan_state(dev, WAN_DISCONNECTED);
}
/* disconnect interrupt handler. */
static void disconnect_intr (cycx_t *card, TX25Cmd *cmd)
{
wan_device_t *wandev = &card->wandev;
- struct device *dev;
+ struct net_device *dev;
u8 lcn;
cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
dprintk(KERN_INFO "disconnect_intr:lcn=%d\n", lcn);
- x25_disconnect_response(card, 0, lcn);
- if ((dev = get_dev_by_lcn(wandev, lcn)) != NULL)
- set_chan_state(dev, WAN_DISCONNECTED, IN_INTR);
+ if ((dev = get_dev_by_lcn(wandev, lcn)) != NULL) {
+ x25_channel_t *chan = dev->priv;
+
+ x25_disconnect_response(card, chan->link, lcn);
+ set_chan_state(dev, WAN_DISCONNECTED);
+ } else
+ x25_disconnect_response(card, 0, lcn);
}
/* LOG interrupt handler. */
@@ -960,55 +941,51 @@
printk(KERN_INFO "%s: %s\n", msg, hex);
}
#endif
-/* CYCLOM X Firmware-Specific Functions
- *
- * Almost all X.25 commands can unexpetedly fail due to so called 'X.25
- * asynchronous events' such as restart, interrupt, incoming call request,
- * call clear request, etc. They can't be ignored and have to be dealt with
- * immediately. To tackle with this problem we execute each interface command
- * in a loop until good return code is received or maximum number of retries
- * is reached. Each interface command returns non-zero return code, an
- * asynchronous event/error handler x25_error() is called.
- */
+/* CYCLOM X Firmware-Specific Functions */
/* Exec x25 command. */
static int x25_exec (cycx_t *card, int command, int link,
- void *data1, int len1, void *data2, int len2)
+ void *d1, int len1, void *d2, int len2)
{
TX25Cmd c;
+ unsigned long flags;
u32 addr = 0x1200 + 0x2E0 * link + 0x1E2;
+ u8 retry = MAX_CMD_RETRY;
int err = 0;
c.command = command;
c.link = link;
c.len = len1 + len2;
- if (test_and_set_bit(0, (void*)&card->u.x.critical))
- return -EAGAIN;
+ spin_lock_irqsave(&card->u.x.lock, flags);
/* write command */
cycx_poke(&card->hw, X25_MBOX_OFFS, &c, sizeof(c) - sizeof(c.buf));
/* write x25 data */
- if (data1) {
- cycx_poke(&card->hw, addr, data1, len1);
+ if (d1) {
+ cycx_poke(&card->hw, addr, d1, len1);
- if (data2)
+ if (d2) {
if (len2 > 254) {
u32 addr1 = 0xA00 + 0x400 * link;
- cycx_poke(&card->hw, addr + len1, data2, 249);
- cycx_poke(&card->hw, addr1, ((u8*) data2) + 249,
+ cycx_poke(&card->hw, addr + len1, d2, 249);
+ cycx_poke(&card->hw, addr1, ((u8*) d2) + 249,
len2 - 249);
} else
- cycx_poke(&card->hw, addr + len1, data2, len2);
+ cycx_poke(&card->hw, addr + len1, d2, len2);
+ }
}
/* generate interruption, executing command */
cycx_intr(&card->hw);
/* wait till card->mbox == 0 */
- err = cycx_exec(card->mbox);
- card->u.x.critical = 0;
+ do {
+ err = cycx_exec(card->mbox);
+ } while (retry-- && err);
+
+ spin_unlock_irqrestore(&card->u.x.lock, flags);
return err;
}
@@ -1110,6 +1087,7 @@
while (len) {
*d++ = '0' + (*s >> 4);
+
if (--len) {
*d++ = '0' + (*s & 0x0F);
--len;
@@ -1125,9 +1103,8 @@
static int x25_place_call (cycx_t *card, x25_channel_t *chan)
{
int err = 0,
- retry = MAX_CMD_RETRY,
len;
- char data[64],
+ char d[64],
nibble = 0,
mylen = chan->local_addr ? strlen(chan->local_addr) : 0,
remotelen = strlen(chan->addr);
@@ -1143,24 +1120,24 @@
set_bit(key, (void*)&card->u.x.connection_keys);
++key;
dprintk(KERN_INFO "%s:x25_place_call:key=%d\n", card->devname, key);
- memset(data, 0, sizeof(data));
- data[1] = key; /* user key */
- data[2] = 0x10;
- data[4] = 0x0B;
-
- len = byte_to_nibble(chan->addr, data + 6, &nibble);
- len += chan->local_addr ? byte_to_nibble(chan->local_addr,
- data + 6 + len, &nibble) : 0;
+ memset(d, 0, sizeof(d));
+ d[1] = key; /* user key */
+ d[2] = 0x10;
+ d[4] = 0x0B;
+
+ len = byte_to_nibble(chan->addr, d + 6, &nibble);
+
+ if (chan->local_addr)
+ len += byte_to_nibble(chan->local_addr, d + 6 + len, &nibble);
+
if (nibble)
++len;
- data[5] = mylen << 4 | remotelen;
- data[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanx to Daniela :) */
-
- do err = x25_exec(card, X25_CONNECT_REQUEST, chan->link,
- &data, 7 + len + 1, NULL, 0);
- while (err && retry--);
- if (err)
+ d[5] = mylen << 4 | remotelen;
+ d[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanx to Daniela :) */
+
+ if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link,
+ &d, 7 + len + 1, NULL, 0)) != 0)
clear_bit(--key, (void*)&card->u.x.connection_keys);
else {
chan->lcn = -key;
@@ -1173,82 +1150,60 @@
/* Place X.25 CONNECT RESPONSE. */
static int x25_connect_response (cycx_t *card, x25_channel_t *chan)
{
- int err = 0,
- retry = MAX_CMD_RETRY;
- char data[32];
+ u8 d[8];
- memset(data, 0, sizeof(data));
- data[0] = data[3] = chan->lcn;
- data[2] = 0x10;
- data[4] = 0x0F;
- data[7] = 0xCC; /* TCP/IP over X.25, thanx Daniela */
-
- do err = x25_exec(card, X25_CONNECT_RESPONSE, chan->link,
- &data, 8, NULL, 0);
- while (err && retry--);
+ memset(d, 0, sizeof(d));
+ d[0] = d[3] = chan->lcn;
+ d[2] = 0x10;
+ d[4] = 0x0F;
+ d[7] = 0xCC; /* TCP/IP over X.25, thanx Daniela */
- return err;
+ return x25_exec(card, X25_CONNECT_RESPONSE, chan->link, &d, 8, NULL, 0);
}
/* Place X.25 DISCONNECT RESPONSE. */
static int x25_disconnect_response (cycx_t *card, u8 link, u8 lcn)
{
- int err = 0,
- retry = MAX_CMD_RETRY;
- char data[5];
+ char d[5];
- memset(data, 0, sizeof(data));
- data[0] = data[3] = lcn;
- data[2] = 0x10;
- data[4] = 0x17;
- do err = x25_exec(card, X25_DISCONNECT_RESPONSE, link,
- &data, 5, NULL, 0);
- while (err && retry--);
-
- return err;
+ memset(d, 0, sizeof(d));
+ d[0] = d[3] = lcn;
+ d[2] = 0x10;
+ d[4] = 0x17;
+ return x25_exec(card, X25_DISCONNECT_RESPONSE, link, &d, 5, NULL, 0);
}
/* Clear X.25 call. */
static int x25_clear_call (cycx_t *card, u8 link, u8 lcn, u8 cause, u8 diagn)
{
- int retry = MAX_CMD_RETRY,
- err;
- u8 data[7];
-
- memset(data, 0, sizeof(data));
- data[0] = data[3] = lcn;
- data[2] = 0x10;
- data[4] = 0x13;
- data[5] = cause;
- data[6] = diagn;
+ u8 d[7];
- do err = x25_exec(card, X25_DISCONNECT_REQUEST, link, data, 7, NULL, 0);
- while (err && retry--);
+ memset(d, 0, sizeof(d));
+ d[0] = d[3] = lcn;
+ d[2] = 0x10;
+ d[4] = 0x13;
+ d[5] = cause;
+ d[6] = diagn;
- return err;
+ return x25_exec(card, X25_DISCONNECT_REQUEST, link, d, 7, NULL, 0);
}
/* Send X.25 data packet. */
static int x25_send (cycx_t *card, u8 link, u8 lcn, u8 bitm, int len, void *buf)
{
- int err = 0,
- retry = MAX_CMD_RETRY;
- u8 data[] = "?\xFF\x10??";
-
- data[0] = data[3] = lcn;
- data[4] = bitm;
+ u8 d[] = "?\xFF\x10??";
- do err = x25_exec(card, X25_DATA_REQUEST, link, &data, 5, buf, len);
- while (err && retry--);
+ d[0] = d[3] = lcn;
+ d[4] = bitm;
- return err;
+ return x25_exec(card, X25_DATA_REQUEST, link, &d, 5, buf, len);
}
/* Miscellaneous */
/* Find network device by its channel number. */
-static struct device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn)
+static struct net_device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn)
{
- struct device *dev = wandev->dev;
+ struct net_device *dev = wandev->dev;
for (; dev; dev = dev->slave)
if (((x25_channel_t*)dev->priv)->lcn == lcn)
@@ -1257,9 +1212,9 @@
}
/* Find network device by its remote dte address. */
-static struct device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte)
+static struct net_device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte)
{
- struct device *dev = wandev->dev;
+ struct net_device *dev = wandev->dev;
for (; dev; dev = dev->slave)
if (!strcmp (((x25_channel_t*)dev->priv)->addr, dte))
@@ -1274,7 +1229,7 @@
* Return: 0 connected
* >0 connection in progress
* <0 failure */
-static int chan_connect (struct device *dev)
+static int chan_connect (struct net_device *dev)
{
x25_channel_t *chan = dev->priv;
cycx_t *card = chan->card;
@@ -1286,31 +1241,31 @@
card->devname, chan->addr);
if (x25_place_call(card, chan))
return -EIO;
- set_chan_state(dev, WAN_CONNECTING, OUT_INTR);
+ set_chan_state(dev, WAN_CONNECTING);
return 1;
} else
- set_chan_state(dev, WAN_CONNECTED, OUT_INTR);
+ set_chan_state(dev, WAN_CONNECTED);
return 0;
}
/* Disconnect logical channel.
* o if SVC then clear X.25 call */
-static void chan_disc (struct device *dev)
+static void chan_disc (struct net_device *dev)
{
x25_channel_t *chan = dev->priv;
if (chan->svc) {
x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0);
- set_chan_state(dev, WAN_DISCONNECTING, OUT_INTR);
+ set_chan_state(dev, WAN_DISCONNECTING);
} else
- set_chan_state(dev, WAN_DISCONNECTED, OUT_INTR);
+ set_chan_state(dev, WAN_DISCONNECTED);
}
/* Called by kernel timer */
-static void chan_timer (unsigned long data)
+static void chan_timer (unsigned long d)
{
- struct device *dev = (struct device*) data;
+ struct net_device *dev = (struct net_device*) d;
x25_channel_t *chan = dev->priv;
switch (chan->state) {
@@ -1325,16 +1280,13 @@
}
/* Set logical channel state. */
-static void set_chan_state (struct device *dev, u8 state, u8 outside_intr)
+static void set_chan_state (struct net_device *dev, u8 state)
{
x25_channel_t *chan = dev->priv;
cycx_t *card = chan->card;
u32 flags = 0;
- if (outside_intr)
- spin_lock(&card->lock);
- else
- spin_lock_irqsave(&card->lock, flags);
+ spin_lock_irqsave(&card->lock, flags);
if (chan->state != state) {
if (chan->svc && chan->state == WAN_CONNECTED)
@@ -1370,16 +1322,14 @@
*(unsigned short*)dev->dev_addr = 0;
chan->lcn = 0;
}
+ dev->tbusy = 0;
break;
}
chan->state = state;
}
- if (outside_intr)
- spin_unlock(&card->lock);
- else
- spin_unlock_irqrestore(&card->lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
}
/* Send packet on a logical channel.
@@ -1395,7 +1345,7 @@
* the packet into 'complete sequence' using M-bit.
* 2. When transmission is complete, an event notification should be issued
* to the router. */
-static int chan_send (struct device *dev, struct sk_buff *skb)
+static int chan_send (struct net_device *dev, struct sk_buff *skb)
{
x25_channel_t *chan = dev->priv;
cycx_t *card = chan->card;
@@ -1468,7 +1418,7 @@
return val;
}
-static void reset_timer(struct device *dev)
+static void reset_timer(struct net_device *dev)
{
x25_channel_t *chan = dev->priv;
@@ -1520,7 +1470,7 @@
static void x25_dump_devs(wan_device_t *wandev)
{
- struct device *dev = wandev->dev;
+ struct net_device *dev = wandev->dev;
printk (KERN_INFO "x25 dev states\n");
printk (KERN_INFO "name: addr: tbusy:\n");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)