⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iucv.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    struct iucv_priv *privptr;    char iucv_host[8]   ={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};     char vmident[16]    ={0xf0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,                          0xf0,0x40,0x40,0x40,0x40,0x40,0x40,0x40};#ifdef DEBUG    printk(  "iucv: iucv_open, device: %s\n",dev->name);#endif    privptr = (struct iucv_priv *)(dev->priv);    if(privptr->pathid != -1) {       netif_start(dev);       netif_start_queue(dev);       return 0;    }    if ((rc = iucv_connect(privptr->command_buffer,                           privptr->userid,                           iucv_host,                           vmident,                           &iucv_used_pathid))!=0) {      printk(  "iucv: iucv connect failed with rc %X\n",rc);      iucv_retrieve_buffer(privptr->command_buffer);      return -ENODEV;    }    privptr->pathid = iucv_used_pathid;    iucv_pathid[dev-iucv_devs]=privptr->pathid;#ifdef DEBUG    printk(  "iucv: iucv_connect ended with rc: %X\n",rc);    printk(  "iucv[%d] pathid %X \n",(int)(dev-iucv_devs),privptr->pathid);#endif    netif_start(dev);    netif_start_queue(dev);    return 0;}/*-----------------------------------------------------------------------*//* Receive a packet: retrieve, encapsulate and pass over to upper levels *//*-----------------------------------------------------------------------*/void iucv_rx(net_device *dev, int len, unsigned char *buf){  struct sk_buff *skb;  struct iucv_priv *privptr = (struct iucv_priv *)dev->priv;#ifdef DEBUG  printk(  "iucv: iucv_rx len: %X, device %s\n",len,dev->name);  printk(  "iucv rx: received orig:\n");  dumpit(buf,len);#endif  /* strip iucv header now */  len = len - 2;   /* short header */  buf = buf + 2;   /* short header */  skb = dev_alloc_skb(len+2); /* why +2 ? alignment ? */  if (!skb) {    printk(  "iucv rx: low on mem, returning...\n");    return;  }  skb_reserve(skb, 2);                        /* align IP on 16B boundary*/  memcpy(skb_put(skb, len), buf, len);#ifdef DEBUG  printk(  "iucv rx: data before netif_rx()\n");  dumpit(buf,len);#endif  /* Write metadata, and then pass to the receive level */  skb->mac.raw = skb->data;  skb->pkt_type = PACKET_HOST;  skb->dev = dev;  skb->protocol = htons(ETH_P_IP);  skb->ip_summed = CHECKSUM_UNNECESSARY;                /* don't check it*/  privptr->stats.rx_packets++;  netif_rx(skb);  return;} /* end  iucv_rx() *//*----------------------------*//* handle interrupts          *//*----------------------------*/void do_iucv_interrupt(void){  int rc;  struct in_device *indev;  struct in_ifaddr *inaddr;  unsigned long len=0;  net_device *dev=0;  struct iucv_priv *privptr;  INTERRUPT_T * extern_int_buffer;  unsigned short iucv_data_len=0;  unsigned short iucv_next=0;  unsigned char * rcvptr;    /* get own buffer: */  extern_int_buffer = (INTERRUPT_T*) iucv_ext_int_buffer;    netif_enter_interrupt(dev);        /* lock ! */  #ifdef DEBUG  printk(  "iucv: do_iucv_interrupt %x received; pathid: %02X\n",	   extern_int_buffer->iptype,extern_int_buffer->ippathid);  printk(   "iucv: extern_int_buffer:\n");  dumpit((char *)&extern_int_buffer[0],40);#endif    switch (extern_int_buffer->iptype)    {    case 0x01: /* connection pending ext interrrupt */#ifdef DEBUG      printk(  "iucv: connection pending IRQ.\n");#endif            rc = iucv_accept(glob_command_buffer,		       extern_int_buffer->ippathid);      if (rc != 0) {	printk(  "iucv: iucv_accept failed with rc: %X\n",rc);	iucv_retrieve_buffer(glob_command_buffer);	break;      }#ifdef DEBUG      dumpit(&((char *)extern_int_buffer)[8],8);#endif      dev = get_device_from_userid(&((char*)extern_int_buffer)[8]);      privptr = (struct iucv_priv *)(dev->priv);      privptr->pathid =  extern_int_buffer->ippathid;      #ifdef DEBUG      printk(  "iucv: iucv_accept ended with rc: %X\n",rc);      printk(  "iucv: device %s found.\n",dev->name);#endif      break;          case 0x02: /* connection completed ext interrrupt */      /* set own global IP address */      /* & set global routing addr */#ifdef DEBUG      printk(  "connection completed.\n");#endif            if( extern_int_buffer->ipmsgtag !=0)	{	  /* get ptr's to kernel struct with local & broadcast address */	  dev = get_device_from_pathid(extern_int_buffer->ippathid);	  privptr = (struct iucv_priv *)(dev->priv);	  indev = dev->ip_ptr;	  inaddr = (struct in_ifaddr*) indev->ifa_list;	}      break;                case 0x03: /* connection severed ext interrrupt */      /* we do not handle this one at this time */#ifdef DEBUG      printk(  "connection severed.\n");#endif      break;                case 0x04: /* connection quiesced ext interrrupt */      /* we do not handle this one at this time */#ifdef DEBUG      printk(  "connection quiesced.\n");#endif      break;                case 0x05: /* connection resumed ext interrrupt */      /* we do not handle this one at this time */#ifdef DEBUG      printk(  "connection resumed.\n");#endif      break;                case 0x06: /* priority message complete ext interrupt */    case 0x07: /* non priority message complete ext interrupt */      /* send it to iucv_rx for handling */#ifdef DEBUG      printk(  "message completed.\n");#endif            if (extern_int_buffer->ipaudit ==0)  /* ok case */	{#ifdef DEBUG	  printk(  "iucv: msg complete interrupt successful, rc: %X\n",		   (unsigned int)extern_int_buffer->ipaudit);#endif	  ;	}      else	{	  printk(  "iucv: msg complete interrupt error, rc: %X\n",		   (unsigned int)extern_int_buffer->ipaudit);	}      /* a transmission is over: tell we are no more busy */      dev = get_device_from_pathid(extern_int_buffer->ippathid);      privptr = (struct iucv_priv *)(dev->priv);      privptr->stats.tx_packets++;      netif_wake_queue(dev);                /* transmission is no longer busy*/      break;                case 0x08: /* priority message pending */    case 0x09: /* non priority message pending */#ifdef DEBUG      printk(  "message pending.\n");#endif      dev = get_device_from_pathid(extern_int_buffer->ippathid);      privptr = (struct iucv_priv *)(dev->priv);      rcvptr = &privptr->receive_buffer[0];            /* re-set receive buffer */      memset(privptr->receive_buffer,0,privptr->receive_buffer_len);      len = privptr->receive_buffer_len;              /* get data now */        if (extern_int_buffer->ipflags1 & 0x80)	  {  /* data is in the message */#ifdef DEBUG	    printk(  "iucv: iucv_receive data is in header!\n");#endif	    memcpy(privptr->receive_buffer,		   (char *)extern_int_buffer->iprmmsg1,		   (unsigned long)(extern_int_buffer->iprmmsg2));	  }        else /* data is in buffer, do a receive */	  {	    rc = iucv_receive(privptr->command_buffer,rcvptr,len);	    if (rc != 0  || len == 0)	      {		printk(  "iucv: iucv_receive failed with rc: %X, length: %lX\n",rc,len);		iucv_retrieve_buffer(privptr->command_buffer);		break;	      }	  } /* end else */	      iucv_next = 0;       /* get next packet offset */        iucv_data_len= *((unsigned short*)rcvptr);         do{ /* until receive buffer is empty, i.e. iucv_next == 0 ! */        /* get data length:    */        iucv_data_len= iucv_data_len - iucv_next;	#ifdef DEBUG        printk(  "iucv: iucv_receive: len is %02X, last: %02X\n",		 iucv_data_len,iucv_next);#endif        /* transmit upstairs */        iucv_rx(dev,(iucv_data_len),rcvptr);	#ifdef DEBUG        printk(  "iucv: transaction complete now.\n");#endif        iucv_next = *((unsigned short*)rcvptr);        rcvptr = rcvptr + iucv_data_len;        /* get next packet offset */          iucv_data_len= *((unsigned short*)rcvptr);	      } while (iucv_data_len != 0);      netif_start_queue(dev);                 /* transmission is no longer busy*/      break;          default:      printk(  "unknown iucv interrupt \n");      break;          } /* end switch */  netif_exit_interrupt(dev);              /* release lock*/  #ifdef DEBUG  printk(  "iucv: leaving do_iucv_interrupt.\n");#endif  }  /* end    do_iucv_interrupt()  *//*-------------------------------------------*//*   Transmit a packet (low level interface) *//*-------------------------------------------*/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.       */  /* In other words, this function implements the iucv behaviour,*/  /* while all other procedures are rather device-independent     */  struct iucv_priv *privptr;  int rc, recv_len=2000;    privptr = (struct iucv_priv *)(dev->priv);  #ifdef DEBUG  printk(  "iucv: iucv_hw_tx, device %s\n",dev->name);  printk(  "iucv: hw_TX_data len: %X\n",len);  dumpit(send_buf,len);#endif    /* I am paranoid. Ain't I? */  if (len < sizeof(struct iphdr))    {      printk(  "iucv: Hmm... packet too short (%i octets)\n",len);      return -EINVAL;    }    /*   * build IUCV header (preceeding halfword offset)      * works as follows: Each packet is preceded by the    * halfword offset to the next one.    * The last packet is followed by an offset of zero.   * E.g., AL2(12),10-byte packet, AL2(34), 32-byte packet, AL2(0)   */    memcpy(&privptr->send_buffer[2],send_buf,len+2);  privptr->send_buffer[len+2] = 0;  privptr->send_buffer[len+3] = 0;  *((unsigned short*) &privptr->send_buffer[0]) = len + 2;  #ifdef DEBUG  printk(  "iucv: iucv_hw_tx, device %s\n",dev->name);  printk(  "iucv: send len: %X\n",len+4);  dumpit(privptr->send_buffer,len+4);#endif  *((unsigned short*) &privptr->send_buffer[0]) = len + 2;    /* Ok, now the packet is ready for transmission: send it. */  if ((rc = iucv_send(privptr->command_buffer,		      privptr->pathid,		      &privptr->send_buffer[0],len+4,		      privptr->recv_buf,recv_len))!=0) {    printk(  "iucv: send_iucv failed, rc: %X\n",rc);    iucv_retrieve_buffer(privptr->command_buffer);  }#ifdef DEBUG  printk(  "iucv: send_iucv ended, rc: %X\n",rc);#endif  return rc;} /* end   iucv_hw_tx()  *//*------------------------------------------*//* Transmit a packet (called by the kernel) *//*------------------------------------------*/int iucv_tx(struct sk_buff *skb, net_device *dev){    int retval=0;    struct iucv_priv *privptr;    if (dev == NULL)    {      printk("iucv: NULL dev passed\n");      return 0;    }    privptr = (struct iucv_priv *) (dev->priv);    if (skb == NULL)    {      printk("iucv: %s: NULL buffer passed\n", dev->name);      privptr->stats.tx_errors++;      return 0;    }#ifdef DEBUG    printk(  "iucv: enter iucv_tx, using %s\n",dev->name);#endif    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);    }    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 */    retval = iucv_hw_tx(skb->data, skb->len, dev);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -