📄 iucv.c
字号:
/* * drivers/s390/net/iucv.c * Network driver for VM using iucv * * S390 version * 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__#define __KERNEL__#endif#include <linux/version.h>#include <linux/sched.h>#include <linux/kernel.h> /* printk() */#include <linux/malloc.h> /* kmalloc() */#include <linux/errno.h> /* error codes */#include <linux/types.h> /* size_t */#include <linux/interrupt.h> /* mark_bh */#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 */#include <linux/tcp.h> /* struct tcphdr */#include <linux/skbuff.h>#include <linux/init.h>#include <linux/string.h>#include <asm/checksum.h>#include <asm/io.h>#include <asm/string.h>#include "iucv.h"#define DEBUG123#define MAX_DEVICES 10extern char _ascebc[];/* * global structures */static char iucv_userid[MAX_DEVICES][8];static char iucv_ascii_userid[MAX_DEVICES][8];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)));#if LINUX_VERSION_CODE>=0x20300typedef struct net_device net_device;#elsetypedef struct device net_device;#endifnet_device iucv_devs[];/* This structure is private to each device. It is used to pass *//* packets in and out, so there is place for a packet */struct iucv_priv { struct net_device_stats stats; int packetlen; int status; u8 *packetdata; int pathid; /* used device */ unsigned char command_buffer[40] __attribute__((aligned (8))); unsigned char ext_int_buffer[40] __attribute__((aligned (8))); u8* receive_buffer; int receive_buffer_len; u8* send_buffer; int send_buffer_len; char * new_send_buf; /* send buffer ptr */ unsigned char recv_buf[2048]; /* size is just a guess */ unsigned char userid[8];};struct iucv_header { 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=0static __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 */extern inline void b2f0(int code,void* parm){ asm volatile ("LR 1,%1\n\tLR 0,%0\n\t.long 0xb2f01000" :: "d" (code) ,"a" (parm) :"0", "1");}int iucv_enable(void *parms){ MASK_T *parm = parms; memset(parms,0,sizeof(parm)); parm->ipmask = 0xF8; b2f0(SETMASK,parm); memset(parms,0,sizeof(parm)); parm->ipmask = 0xF8; b2f0(SETCMASK,parm); return parm->iprcode;}int iucv_declare_buffer(void *parms, DCLBFR_T *buffer){ DCLBFR_T *parm = parms; memset(parms,0,sizeof(parm)); parm->ipflags1= 0x00; parm->ipbfadr1 = virt_to_phys(buffer); b2f0(DECLARE_BUFFER, parm); return parm->iprcode;}int iucv_retrieve_buffer(void *parms){ DCLBFR_T *parm = parms; memset(parms,0x0,sizeof(parm)); parm->iprcode = 0x0; b2f0(RETRIEVE_BUFFER, parm); return parm->iprcode;}int iucv_connect(void *parms, const char *userid, const char *host, const char *ipusr, unsigned short * used_pathid){ CONNECT_T *parm = parms; /* ipflags was 0x60*/ memset(parms,0x0,sizeof(parm)); parm->ipflags1 = 0x80; parm->ipmsglim = 0x0a; memcpy(parm->ipvmid,userid,8); if (ipusr) memcpy(parm->ipuser,ipusr,16); memcpy(parm->iptarget,host,8); b2f0(CONNECT, parm); *used_pathid = parm->ippathid; return parm->iprcode;}int iucv_accept(void *parms,int pathid){#ifdef DEBUG int i=0;#endif ACCEPT_T *parm = parms; memset(parms,0,sizeof(parm)); parm->ippathid = pathid; parm->ipflags1 = 0x80; parm->ipmsglim = 0x0a;#ifdef DEBUG printk("iucv: iucv_accept input.\n"); for (i=0;i<40; i++) { printk("%02x ",((char *)parms)[i]); } printk("\n");#endif b2f0(ACCEPT, parm); return parm->iprcode;}int iucv_receive(void *parms,void *bufferarray,int len){#ifdef DEBUG int i=0;#endif RECEIVE_T *parm = parms; memset(parms,0x0,sizeof(parm)); /*parm->ipflags1 = 0x42;*/ parm->ipflags1 = 0x0; parm->ipmsgid = 0x0; parm->iptrgcls = 0x0; parm->ipbfadr1 = (ULONG) virt_to_phys(bufferarray); parm->ipbfln1f = len; parm->ipbfln2f = 0x0; b2f0(RECEIVE, parm); if (parm->iprcode == 0) len = parm->ipbfln1f;// len = len-parm->ipbfln1f;#ifdef DEBUG printk("iucv: iucv_receive command input:\n"); for (i=0;i<40;i++) /* show iucv buffer before send */ { printk("%02x ",((char *)parms)[i]); } printk("\n"); printk("iucv: iucv_receive data buffer:\n"); for (i=0;i<len;i++) /* show data received */ { printk("%02x ",((char *)bufferarray)[i]); } printk("\n"); printk("received length: %02x ",len);#endif return parm->iprcode;}int iucv_send(void *parms,int pathid,void *bufferarray,int len, void *recv_buf, int recv_len){#ifdef DEBUG int i=0;#endif SEND_T *parm = parms; memset(parms,0x0,sizeof(parm)); /* parm->ipflags1 = 0x48; ??*/ parm->ippathid = pathid; parm->ipflags1 = 0x14; /* any options ?? */ parm->ipmsgid = 0x0; parm->iptrgcls = 0x0; parm->ipbfadr1 = virt_to_phys(bufferarray); parm->ipbfln1f = len; parm->ipsrccls = 0x0; parm->ipmsgtag = 0x0; parm->ipbfadr2 = virt_to_phys(recv_buf); parm->ipbfln2f = recv_len;#ifdef DEBUG printk("iucv: iucv_send command input:\n"); for (i=0;i<40;i++) /* show iucv buffer before send */ { printk("%02x ",((char *)parms)[i]); } printk("\n"); printk("iucv: iucv_send data buffer:\n"); for (i=0;i<len;i++) /* show send data before send */ { printk("%02x ",((char *)bufferarray)[i]); } printk("\n");#endif b2f0(SEND, parm);#ifdef DEBUGXX printk("iucv: iucv_send buffer after send:\n"); for (i=0;i<len;i++) /* show send buffer after send */ { printk("%1x",((char *)bufferarray)[i]); } printk("\n");#endif return parm->iprcode;}int iucv_sever(void *parms){ SEVER_T *parm = parms; memset(parms,0x0,sizeof(parm)); parm->ippathid = 0x0; parm->ipflags1 = 0x0; parm->iprcode = 0xF; memset(parm->ipuser,0,16); b2f0(SEVER, parm); return parm->iprcode;}#ifdef DEBUG/*--------------------------*//* Dump buffer formatted *//*--------------------------*/static void dumpit(char* buf, int len){ int i; for (i=0;i<len;i++) { if (!(i%16)&&i!=0) printk("\n"); else if (!(i%4)&&i!=0) printk(" "); printk( "%02X",buf[i]); } if (len%16) printk( "\n");}#endif/*--------------------------*//* Get device from pathid *//*--------------------------*/net_device * get_device_from_pathid(int pathid){ int i; for (i=0;i<=MAX_DEVICES;i++) { if (iucv_pathid[i] == pathid) return &iucv_devs[i]; } printk("iucv: get_device_from_pathid: no device for pathid %X\n",pathid); return 0;}/*--------------------------*//* Get device from userid *//*--------------------------*/net_device * get_device_from_userid(char * userid){ int i; net_device * dev; struct iucv_priv *privptr; for (i=0;i<=MAX_DEVICES;i++) { dev = &iucv_devs[i]; privptr = (struct iucv_priv *)(dev->priv); if (memcmp(privptr->userid,userid,8)==0) return &iucv_devs[i]; } printk("iucv: get_device_from_uid: no device for userid %s\n",userid); return 0;}/*--------------------------*//* Open iucv Device Driver *//*--------------------------*/int iucv_open(net_device *dev){ int rc; unsigned short iucv_used_pathid;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -