patch-2.2.16 linux/drivers/s390/net/iucv.c
Next file: linux/drivers/sbus/audio/audio.c
Previous file: linux/drivers/s390/net/ctc.c
Back to the patch index
Back to the overall index
- Lines: 379
- Date:
Wed Jun 7 14:26:43 2000
- Orig file:
v2.2.15/linux/drivers/s390/net/iucv.c
- Orig date:
Wed May 3 17:16:44 2000
diff -urN v2.2.15/linux/drivers/s390/net/iucv.c linux/drivers/s390/net/iucv.c
@@ -3,9 +3,14 @@
* Network driver for VM using iucv
*
* S390 version
- * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Stefan Hegewald <hegewald@de.ibm.com>
* Hartmut Penner <hpenner@de.ibm.com>
+ *
+ * 2.3 Updates Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ * Martin Schwidefsky (schwidefsky@de.ibm.com)
+ *
+
*/
#ifndef __KERNEL__
@@ -19,8 +24,8 @@
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/interrupt.h> /* mark_bh */
-#include <linux/netdevice.h> /* struct device, and other headers */
-#include <linux/inetdevice.h> /* struct device, and other headers */
+#include <linux/netdevice.h> /* struct net_device, and other headers */
+#include <linux/inetdevice.h> /* struct net_device, and other headers */
#include <linux/if_arp.h>
#include <linux/rtnetlink.h>
#include <linux/ip.h> /* struct iphdr */
@@ -31,9 +36,13 @@
#include <asm/checksum.h>
#include <asm/io.h>
#include <asm/string.h>
+#include <asm/s390_ext.h>
#include "iucv.h"
+
+
+
#define DEBUG123
#define MAX_DEVICES 10
@@ -47,7 +56,13 @@
static int iucv_pathid[MAX_DEVICES] = {0};
static unsigned char iucv_ext_int_buffer[40] __attribute__((aligned (8))) ={0};
static unsigned char glob_command_buffer[40] __attribute__((aligned (8)));
-struct device iucv_devs[];
+
+#if LINUX_VERSION_CODE>=0x20300
+typedef struct net_device net_device;
+#else
+typedef struct device net_device;
+#endif
+net_device iucv_devs[];
/* This structure is private to each device. It is used to pass */
@@ -73,6 +88,50 @@
short len;
};
+
+
+static __inline__ int netif_is_busy(net_device *dev)
+{
+#if LINUX_VERSION_CODE<0x02032D
+ return(dev->tbusy);
+#else
+ return(test_bit(LINK_STATE_XOFF,&dev->flags));
+#endif
+}
+
+
+
+#if LINUX_VERSION_CODE<0x02032D
+#define netif_enter_interrupt(dev) dev->interrupt=1
+#define netif_exit_interrupt(dev) dev->interrupt=0
+#define netif_start(dev) dev->start=1
+#define netif_stop(dev) dev->start=0
+
+static __inline__ void netif_stop_queue(net_device *dev)
+{
+ dev->tbusy=1;
+}
+
+static __inline__ void netif_start_queue(net_device *dev)
+{
+ dev->tbusy=0;
+}
+
+static __inline__ void netif_wake_queue(net_device *dev)
+{
+ dev->tbusy=0;
+ mark_bh(NET_BH);
+}
+
+#else
+#define netif_enter_interrupt(dev)
+#define netif_exit_interrupt(dev)
+#define netif_start(dev)
+#define netif_stop(dev)
+#endif
+
+
+
/*
* Following the iucv primitives
*/
@@ -292,7 +351,7 @@
/*--------------------------*/
/* Get device from pathid */
/*--------------------------*/
-struct device * get_device_from_pathid(int pathid)
+net_device * get_device_from_pathid(int pathid)
{
int i;
for (i=0;i<=MAX_DEVICES;i++)
@@ -309,10 +368,10 @@
/*--------------------------*/
/* Get device from userid */
/*--------------------------*/
-struct device * get_device_from_userid(char * userid)
+net_device * get_device_from_userid(char * userid)
{
int i;
- struct device * dev;
+ net_device * dev;
struct iucv_priv *privptr;
for (i=0;i<=MAX_DEVICES;i++)
{
@@ -329,7 +388,7 @@
/*--------------------------*/
/* Open iucv Device Driver */
/*--------------------------*/
-int iucv_open(struct device *dev)
+int iucv_open(net_device *dev)
{
int rc;
unsigned short iucv_used_pathid;
@@ -344,8 +403,8 @@
privptr = (struct iucv_priv *)(dev->priv);
if(privptr->pathid != -1) {
- dev->start = 1;
- dev->tbusy = 0;
+ netif_start(dev);
+ netif_start_queue(dev);
return 0;
}
if ((rc = iucv_connect(privptr->command_buffer,
@@ -365,8 +424,8 @@
printk( "iucv: iucv_connect ended with rc: %X\n",rc);
printk( "iucv[%d] pathid %X \n",(int)(dev-iucv_devs),privptr->pathid);
#endif
- dev->start = 1;
- dev->tbusy = 0;
+ netif_start(dev);
+ netif_start_queue(dev);
return 0;
}
@@ -375,7 +434,7 @@
/*-----------------------------------------------------------------------*/
/* Receive a packet: retrieve, encapsulate and pass over to upper levels */
/*-----------------------------------------------------------------------*/
-void iucv_rx(struct device *dev, int len, unsigned char *buf)
+void iucv_rx(net_device *dev, int len, unsigned char *buf)
{
struct sk_buff *skb;
@@ -421,13 +480,13 @@
/*----------------------------*/
/* handle interrupts */
/*----------------------------*/
-void do_iucv_interrupt(void)
+void do_iucv_interrupt(struct pt_regs *regs, __u16 code)
{
int rc;
struct in_device *indev;
struct in_ifaddr *inaddr;
unsigned long len=0;
- struct device *dev=0;
+ net_device *dev=0;
struct iucv_priv *privptr;
INTERRUPT_T * extern_int_buffer;
unsigned short iucv_data_len=0;
@@ -437,7 +496,7 @@
/* get own buffer: */
extern_int_buffer = (INTERRUPT_T*) iucv_ext_int_buffer;
- dev->interrupt = 1; /* lock ! */
+ netif_enter_interrupt(dev); /* lock ! */
#ifdef DEBUG
printk( "iucv: do_iucv_interrupt %x received; pathid: %02X\n",
@@ -539,8 +598,7 @@
dev = get_device_from_pathid(extern_int_buffer->ippathid);
privptr = (struct iucv_priv *)(dev->priv);
privptr->stats.tx_packets++;
- mark_bh(NET_BH);
- dev->tbusy = 0; /* transmission is no longer busy*/
+ netif_wake_queue(dev); /* transmission is no longer busy*/
break;
@@ -602,7 +660,7 @@
iucv_data_len= *((unsigned short*)rcvptr);
} while (iucv_data_len != 0);
- dev->tbusy = 0; /* transmission is no longer busy*/
+ netif_start_queue(dev); /* transmission is no longer busy*/
break;
default:
@@ -610,7 +668,7 @@
break;
} /* end switch */
- dev->interrupt = 0; /* release lock*/
+ netif_exit_interrupt(dev); /* release lock*/
#ifdef DEBUG
printk( "iucv: leaving do_iucv_interrupt.\n");
@@ -623,7 +681,7 @@
/*-------------------------------------------*/
/* Transmit a packet (low level interface) */
/*-------------------------------------------*/
-int iucv_hw_tx(char *send_buf, int len,struct device *dev)
+int iucv_hw_tx(char *send_buf, int len,net_device *dev)
{
/* This function deals with hw details. */
/* This interface strips off the ethernet header details. */
@@ -689,7 +747,7 @@
/*------------------------------------------*/
/* Transmit a packet (called by the kernel) */
/*------------------------------------------*/
-int iucv_tx(struct sk_buff *skb, struct device *dev)
+int iucv_tx(struct sk_buff *skb, net_device *dev)
{
int retval=0;
@@ -714,14 +772,14 @@
printk( "iucv: enter iucv_tx, using %s\n",dev->name);
#endif
- if (dev->tbusy) /* shouldn't happen*/
+ if (netif_is_busy(dev)) /* shouldn't happen */
{
privptr->stats.tx_errors++;
dev_kfree_skb(skb);
printk("iucv: %s: transmit access conflict ! leaving iucv_tx.\n", dev->name);
}
- dev->tbusy = 1; /* transmission is busy*/
+ netif_stop_queue(dev); /* transmission is busy*/
dev->trans_start = jiffies; /* save the timestamp*/
/* actual deliver of data is device-specific, and not shown here */
@@ -744,14 +802,14 @@
/*---------------*/
/* iucv_release */
/*---------------*/
-int iucv_release(struct device *dev)
+int iucv_release(net_device *dev)
{
int rc =0;
struct iucv_priv *privptr;
privptr = (struct iucv_priv *) (dev->priv);
- dev->start = 0;
- dev->tbusy = 1; /* can't transmit any more*/
+ netif_stop(dev);
+ netif_stop_queue(dev); /* can't transmit any more*/
rc = iucv_sever(privptr->command_buffer);
if (rc!=0)
{
@@ -772,7 +830,7 @@
/*-----------------------------------------------*/
/* Configuration changes (passed on by ifconfig) */
/*-----------------------------------------------*/
-int iucv_config(struct device *dev, struct ifmap *map)
+int iucv_config(net_device *dev, struct ifmap *map)
{
if (dev->flags & IFF_UP) /* can't act on a running interface*/
return -EBUSY;
@@ -789,7 +847,7 @@
/*----------------*/
/* Ioctl commands */
/*----------------*/
-int iucv_ioctl(struct device *dev, struct ifreq *rq, int cmd)
+int iucv_ioctl(net_device *dev, struct ifreq *rq, int cmd)
{
#ifdef DEBUG
printk( "iucv: device %s; iucv_ioctl\n",dev->name);
@@ -800,7 +858,7 @@
/*---------------------------------*/
/* Return statistics to the caller */
/*---------------------------------*/
-struct net_device_stats *iucv_stats(struct device *dev)
+struct net_device_stats *iucv_stats(net_device *dev)
{
struct iucv_priv *priv = (struct iucv_priv *)dev->priv;
#ifdef DEBUG
@@ -815,7 +873,7 @@
* IUCV can handle MTU sizes from 576 to approx. 32000
*/
-static int iucv_change_mtu(struct device *dev, int new_mtu)
+static int iucv_change_mtu(net_device *dev, int new_mtu)
{
#ifdef DEBUG
printk( "iucv: device %s; iucv_change_mtu\n",dev->name);
@@ -833,7 +891,7 @@
/* The init function (sometimes called probe).*/
/* It is invoked by register_netdev() */
/*--------------------------------------------*/
-int iucv_init(struct device *dev)
+int iucv_init(net_device *dev)
{
int rc;
struct iucv_priv *privptr;
@@ -842,6 +900,10 @@
printk( "iucv: iucv_init, device: %s\n",dev->name);
#endif
+ /* request the 0x4000 external interrupt */
+ if (register_external_interrupt(0x4000, do_iucv_interrupt) != 0)
+ panic("Couldn't request external interrupts 0x4000");
+
dev->open = iucv_open;
dev->stop = iucv_release;
dev->set_config = iucv_config;
@@ -926,12 +988,15 @@
*
* string passed: iucv=userid1,...,useridn
*/
-
-__initfunc(int iucv_setup(char* str, int *ints))
+#if LINUX_VERSION_CODE>=0x020300
+static int __init iucv_setup(char *str)
+#else
+__initfunc(void iucv_setup(char *str,int *ints))
+#endif
{
int result=0, i=0,j=0, k=0, device_present=0;
char *s = str;
- struct device * dev ={0};
+ net_device * dev ={0};
#ifdef DEBUG
printk( "iucv: start registering device(s)... \n");
@@ -1006,18 +1071,24 @@
#ifdef DEBUG
printk( "iucv: end register devices, %d devices present\n",device_present);
#endif
- return device_present ? 0 : -ENODEV;
+ /* return device_present ? 0 : -ENODEV; */
+#if LINUX_VERSION_CODE>=0x020300
+ return 1;
+#else
+ return;
+#endif
}
-
-
+#if LINUX_VERSION_CODE>=0x020300
+__setup("iucv=", iucv_setup);
+#endif
/*-------------*/
/* The devices */
/*-------------*/
char iucv_names[MAX_DEVICES*8]; /* MAX_DEVICES eight-byte buffers */
-struct device iucv_devs[MAX_DEVICES] = {
+net_device iucv_devs[MAX_DEVICES] = {
{
iucv_names, /* name -- set at load time */
0, 0, 0, 0, /* shmem addresses */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)