예제 #1
0
static void
smsg_message_pending(iucv_MessagePending *eib, void *pgm_data)
{
	struct smsg_callback *cb;
	unsigned char *msg;
	unsigned short len;
	int rc;

	len = eib->ln1msg2.ipbfln1f;
	msg = kmalloc(len + 1, GFP_ATOMIC|GFP_DMA);
	if (!msg) {
		iucv_reject(eib->ippathid, eib->ipmsgid, eib->iptrgcls);
		return;
	}
	rc = iucv_receive(eib->ippathid, eib->ipmsgid, eib->iptrgcls,
			  msg, len, 0, 0, 0);
	if (rc == 0) {
		msg[len] = 0;
		EBCASC(msg, len);
		spin_lock(&smsg_list_lock);
		list_for_each_entry(cb, &smsg_list, list)
			if (strncmp(msg + 8, cb->prefix, cb->len) == 0) {
				cb->callback(msg + 8);
				break;
			}
		spin_unlock(&smsg_list_lock);
	}
예제 #2
0
파일: iucv.c 프로젝트: dmgerman/original
/*----------------------------*/
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()  */