patch-2.3.16 linux/net/irda/ircomm/ircomm_common.c

Next file: linux/net/irda/ircomm/ircomm_core.c
Previous file: linux/net/irda/ircomm/Makefile
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.15/linux/net/irda/ircomm/ircomm_common.c linux/net/irda/ircomm/ircomm_common.c
@@ -1,1921 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      ircomm_common.c
- * Version:       
- * Description:   An implementation of IrCOMM service interface, 
- *                state machine, and incidental function(s).
- * Status:        Experimental.
- * Author:        Takahide Higuchi <thiguchi@pluto.dti.ne.jp>
- * Source:        irlpt_event.c
- *
- *     Copyright (c) 1998-1999, Takahide Higuchi, <thiguchi@pluto.dti.ne.jp>,
- *     All Rights Reserved.
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of
- *     the License, or (at your option) any later version.
- *
- *     I, Takahide Higuchi, provide no warranty for any of this software.
- *     This material is provided "AS-IS" and at no charge.
- *
- ********************************************************************/
-
-/*
- *    Reference: 
- *    "'IrCOMM':Serial and Parallel Port Emulation Over IR(Wire Replacement)"
- *    version 1.0, which is available at http://www.irda.org/.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
-#include <linux/init.h>
-
-#include <net/irda/irda.h>
-#include <net/irda/irlmp.h>
-#include <net/irda/iriap.h>
-#include <net/irda/irttp.h>
-#include <net/irda/irias_object.h>
-
-#include <net/irda/ircomm_common.h>
-
-static char *revision_date = "Tue May 18 03:11:39 1999";
-
-
-static void ircomm_state_idle(struct ircomm_cb *self, IRCOMM_EVENT event, 
-			      struct sk_buff *skb );
-static void ircomm_state_discoverywait(struct ircomm_cb *self, 
-				       IRCOMM_EVENT event, 
-				       struct sk_buff *skb );
-static void ircomm_state_queryparamwait(struct ircomm_cb *self, 
-					IRCOMM_EVENT event, 
-					struct sk_buff *skb );
-static void ircomm_state_querylsapwait(struct ircomm_cb *self, 
-				       IRCOMM_EVENT event, 
-				       struct sk_buff *skb );
-static void ircomm_state_waiti( struct ircomm_cb *self, IRCOMM_EVENT event, 
-				struct sk_buff *skb );
-static void ircomm_state_waitr( struct ircomm_cb *self, IRCOMM_EVENT event, 
-				struct sk_buff *skb );
-static void ircomm_state_conn( struct ircomm_cb *self, IRCOMM_EVENT event, 
-			       struct sk_buff *skb );
-static void ircomm_do_event( struct ircomm_cb *self, IRCOMM_EVENT event,
-			     struct sk_buff *skb);
-static void ircomm_next_state( struct ircomm_cb *self, IRCOMM_STATE state);
-
-static void ircomm_discovery_indication(discovery_t *discovery);
-static void ircomm_tx_controlchannel(struct ircomm_cb *self );
-static int ircomm_proc_read(char *buf, char **start, off_t offset,
-			    int len, int unused);
-
-static void start_discovering(struct ircomm_cb *self);
-static void query_lsapsel(struct ircomm_cb * self);
-static void query_parameters(struct ircomm_cb *self);
-static void queryias_done(struct ircomm_cb *self);
-static void ircomm_getvalue_confirm(int result, __u16 obj_id, 
-				    struct ias_value *value, void *priv);
-
-
-struct ircomm_cb *discovering_instance;
-
-/*
- * debug parameter ircomm_cs:
- *  0 = client/server, 1 = client only 2 = server only
- * usage for example: 
- *  insmod ircomm ircomm_cs=1
- *  LILO boot : Linux ircomm_cs=2   etc.
- */
-
-static int ircomm_cs = 0;
-MODULE_PARM(ircomm_cs, "i");
-
-
-
-static char *ircommstate[] = {
-	"IDLE",
-
-	"DISCOVERY_WAIT",
-	"QUERYPARAM_WAIT",
-	"QUERYLSAP_WAIT",
-
-	"WAITI",
-	"WAITR",
-	"CONN",
-};
-
-static char *ircommservicetype[] = {
-	"N/A",
-	"THREE_WIRE_RAW",
-	"THREE_WIRE",
-	"NINE_WIRE",
-	"CENTRONICS",
-};
-static char *ircommporttype[] = {
-	"Unknown",
-	"SERIAL",
-	"PARALLEL",
-};
-
-
-struct ircomm_cb **ircomm = NULL;
-
-static char *ircommevent[] = {
-	"IRCOMM_CONNECT_REQUEST",
-	"TTP_CONNECT_INDICATION",
-	"LMP_CONNECT_INDICATION",
-
-	"TTP_CONNECT_CONFIRM",
-	"TTP_DISCONNECT_INDICATION",
-	"LMP_CONNECT_CONFIRM",
-	"LMP_DISCONNECT_INDICATION",
-
-	"IRCOMM_CONNECT_RESPONSE",
-	"IRCOMM_DISCONNECT_REQUEST",
-
-	"TTP_DATA_INDICATION",
-	"IRCOMM_DATA_REQUEST",
-	"LMP_DATA_INDICATION",
-	"IRCOMM_CONTROL_REQUEST",
-
-	"DISCOVERY_INDICATION",
-	"GOT_PARAMETERS",
-	"GOT_LSAPSEL",
-	"QUERYIAS_ERROR",
-};
-
-#ifdef CONFIG_PROC_FS
-extern struct proc_dir_entry *proc_irda;
-#endif
-
-static void (*state[])( struct ircomm_cb *self, IRCOMM_EVENT event,
-			struct sk_buff *skb) = 
-{
-	ircomm_state_idle,
-
-	ircomm_state_discoverywait,
-	ircomm_state_queryparamwait,
-	ircomm_state_querylsapwait,
-
-	ircomm_state_waiti,
-	ircomm_state_waitr,
-	ircomm_state_conn,
-};
-
-__initfunc(int ircomm_init(void))
-{
-	int i;
-
-	printk( "Linux-IrDA: IrCOMM protocol ( revision:%s ) \n",
-		revision_date);
-	DEBUG( 4, __FUNCTION__"()\n");
-
-	/* allocate master array */
-
-	ircomm = (struct ircomm_cb **) kmalloc( sizeof(struct ircomm_cb *) *
-						IRCOMM_MAX_CONNECTION,
-						GFP_KERNEL);
-	if ( ircomm == NULL) {
-		printk( KERN_ERR __FUNCTION__"(): kmalloc failed!\n");
-		return -ENOMEM;
-	}
-
-	memset( ircomm, 0, sizeof(struct ircomm_cb *) * IRCOMM_MAX_CONNECTION);
-
-	/* initialize structures */
-	   
-	for(i = 0;i < IRCOMM_MAX_CONNECTION; i++){
-		ircomm[i] = kmalloc( sizeof(struct ircomm_cb), GFP_KERNEL );
-
-		if(!ircomm[i]){
-			printk( KERN_ERR __FUNCTION__"(): kmalloc failed!\n");
-			return -ENOMEM;
-		} 
-
-		
-		memset( ircomm[i], 0, sizeof(struct ircomm_cb));
-
-		ircomm[i]->magic = IRCOMM_MAGIC;
-		/* default settings */
-		ircomm[i]->data_format = CS8;
-		ircomm[i]->flow_ctrl = USE_RTS|USE_DTR;  /*TODO: is this OK? */
-		ircomm[i]->xon_char = 0x11; 
-		ircomm[i]->xoff_char = 0x13;
-		ircomm[i]->enq_char = 0x05;
-		ircomm[i]->ack_char = 0x06;  
-
-		ircomm[i]->max_header_size = COMM_MAX_HEADER_SIZE;
-		ircomm[i]->tx_max_sdu_size = COMM_DEFAULT_SDU_SIZE;
-		ircomm[i]->rx_max_sdu_size = SAR_DISABLE;  
-		ircomm[i]->ctrl_skb = dev_alloc_skb(COMM_DEFAULT_SDU_SIZE
-						    + COMM_MAX_HEADER_SIZE);
-		if (ircomm[i]->ctrl_skb == NULL){
-			DEBUG(0,"ircomm:init_module:alloc_skb failed!\n");
-			return -ENOMEM;
-		}
-
-		skb_reserve(ircomm[i]->ctrl_skb,COMM_MAX_HEADER_SIZE);
-
-	}
-
-	/*
-	 * we register /proc/irda/ircomm
-	 */
-
-#ifdef CONFIG_PROC_FS
-	create_proc_entry("ircomm", 0, proc_irda)->get_info = ircomm_proc_read;
-#endif /* CONFIG_PROC_FS */
-
-	discovering_instance = NULL;
-	return 0;
-}
-
-#ifdef MODULE
-void ircomm_cleanup(void)
-{
-	int i;
-
-	DEBUG( 4, "ircomm:cleanup_module\n");
-	/*
-	 * free some resources
-	 */
-	if (ircomm) {
-		for (i=0; i<IRCOMM_MAX_CONNECTION; i++) {
-			if (ircomm[i]) {
-
-				if(ircomm[i]->ctrl_skb){
-					dev_kfree_skb(ircomm[i]->ctrl_skb);
-
-					ircomm[i]->ctrl_skb = NULL;
-				}
-
-				DEBUG( 4, "freeing structures(%d)\n",i);
-				kfree(ircomm[i]);
-				ircomm[i] = NULL;
-			}
-		}
-		DEBUG( 4, "freeing master array\n");
-		kfree(ircomm);
-		ircomm = NULL;
-	}
-
-#ifdef CONFIG_PROC_FS
-	remove_proc_entry("ircomm", proc_irda);
-#endif /* CONFIG_PROC_FS */
-}
-#endif /* MODULE */
-
-/*
- * ---------------------------------------------------------------------- 
- * callbacks which accept incoming indication/confirm from IrTTP  (or IrLMP)
- * ---------------------------------------------------------------------- 
- */
-
-static int ircomm_accept_data_indication(void *instance, void *sap, 
-					 struct sk_buff *skb)
-{
-	struct ircomm_cb *self = (struct ircomm_cb *) instance;
-
-	ASSERT(self != NULL, return -1;);
-	ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
-	ASSERT(skb != NULL, return -1;);
-       
-	DEBUG(4,__FUNCTION__"():\n");
-	ircomm_do_event(self, TTP_DATA_INDICATION, skb);
-	self->rx_packets++;
-	
-	return 0;
-}
-
-static void ircomm_accept_connect_confirm(void *instance, void *sap,
-					  struct qos_info *qos, 
-					  __u32 max_sdu_size, 
-					  __u8 max_header_size,
-					  struct sk_buff *skb)
-{
-	struct ircomm_cb *self = (struct ircomm_cb *) instance;
-
-	ASSERT(self != NULL, return;);
-	ASSERT(self->magic == IRCOMM_MAGIC, return;);
-	ASSERT(skb != NULL, return;);
-	ASSERT(qos != NULL, return;);
-
-	DEBUG(0,__FUNCTION__"(): got connected!\n");
-
-	if (max_sdu_size == SAR_DISABLE)
-		self->tx_max_sdu_size =(qos->data_size.value - max_header_size
-					- COMM_HEADER_SIZE);
-	else {
-		ASSERT(max_sdu_size >= COMM_DEFAULT_SDU_SIZE, return;);
-		/* use fragmentation */
-		self->tx_max_sdu_size = max_sdu_size - COMM_HEADER_SIZE;
-	}
-
-	self->qos = qos;
-	self->max_header_size = max_header_size + COMM_HEADER_SIZE;
-	self->null_modem_mode = 0;         /* disable null modem emulation */
-
-	ircomm_do_event(self, TTP_CONNECT_CONFIRM, skb);
-}
-
-static void ircomm_accept_connect_indication(void *instance, void *sap,
-					     struct qos_info *qos,
-					     __u32 max_sdu_size,
-					     __u8 max_header_size,
-					     struct sk_buff *skb)
-{
-	struct ircomm_cb *self = (struct ircomm_cb *)instance;
-
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRCOMM_MAGIC, return;);
-	ASSERT( skb != NULL, return;);
-	ASSERT( qos != NULL, return;);
-
-	DEBUG(0,__FUNCTION__"()\n");
-
-	if (max_sdu_size == SAR_DISABLE)
-		self->tx_max_sdu_size =(qos->data_size.value - max_header_size
-					- COMM_HEADER_SIZE);
-	else
-		self->tx_max_sdu_size = max_sdu_size - COMM_HEADER_SIZE;
-
-	self->qos = qos;
-	self->max_header_size = max_header_size + COMM_HEADER_SIZE;
-
-	ircomm_do_event( self, TTP_CONNECT_INDICATION, skb);
-
-	/* stop connecting */
-	wake_up_interruptible( &self->discovery_wait);
-	wake_up_interruptible( &self->ias_wait);
-
-}
-
-static void ircomm_accept_disconnect_indication(void *instance, void *sap, 
-					 LM_REASON reason,
-					 struct sk_buff *skb)
-{
-	struct ircomm_cb *self = (struct ircomm_cb *)instance;
-
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRCOMM_MAGIC, return;);
-
-	DEBUG(0,__FUNCTION__"():\n");
-	ircomm_do_event( self, TTP_DISCONNECT_INDICATION, skb);
-
-}
-
-static void ircomm_accept_flow_indication( void *instance, void *sap,
-					   LOCAL_FLOW cmd)
-{
-	IRCOMM_CMD command;
-	struct ircomm_cb *self = (struct ircomm_cb *)instance;
-
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRCOMM_MAGIC, return;);
-
-	switch(cmd){
-	case FLOW_START:
-		DEBUG(4,__FUNCTION__"():START\n"); 
-		command = TX_READY;
-		self->ttp_stop = 0;
-		if(self->notify.flow_indication)
-			self->notify.flow_indication( self->notify.instance, 
-						      self, command);
-		break;
-		
-	case FLOW_STOP:
-		DEBUG(4,__FUNCTION__":STOP\n"); 
-		command = TX_BUSY;
-		self->ttp_stop = 1;
-		if(self->notify.flow_indication)
-			self->notify.flow_indication( self->notify.instance, 
-						      self, command);
-		break;
-
-	default:
-		DEBUG(0,__FUNCTION__"();unknown status!\n"); 
-	}
-
-}
-
-
-/*
- * ircomm_discovery_indication()
- *    Remote device is discovered, try query the remote IAS to see which
- *    device it is, and which services it has.
- */
-
-static void ircomm_discovery_indication(discovery_t *discovery)
-{
-	struct ircomm_cb *self;
-
-	self = discovering_instance;
-	if(self == NULL)
-		return;
-	ASSERT(self->magic == IRCOMM_MAGIC, return;);
-
-	self->daddr = discovery->daddr;
-	self->saddr = discovery->saddr;
-
-	DEBUG( 0, __FUNCTION__"():daddr=%08x\n", self->daddr);
-
-	ircomm_do_event(self, DISCOVERY_INDICATION, NULL);
-	return;
-}
-
-/*
- * ircomm_getvalue_confirm()
- * handler for iriap_getvaluebyclass_request() 
- */
-static void ircomm_getvalue_confirm(int result, __u16 obj_id, 
-				    struct ias_value *value, void *priv)
-{
-	struct ircomm_cb *self = (struct ircomm_cb *) priv;
-	struct sk_buff *skb= NULL;
-	__u8 *frame;
-	__u8 servicetype = 0 ;
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRCOMM_MAGIC, return;);
-
-	/* Check if request succeeded */
-	if (result != IAS_SUCCESS) {
-		DEBUG( 0, __FUNCTION__ "(), got NULL value!\n");
-		ircomm_do_event(self, QUERYIAS_ERROR, NULL);
-		return;
-	}
-
-	DEBUG(4, __FUNCTION__"():type(%d)\n", value->type);
-
-	self->ias_type = value->type;
-	switch(value->type){
- 	case IAS_OCT_SEQ:
-		
-		DEBUG(4, __FUNCTION__"():got octet sequence:\n");
-#if 0
-		{
-			int i;
-			for ( i=0;i<value->len;i++)
-				printk("%02x",
-				       (__u8)(*(value->t.oct_seq + i)));
-			printk("\n");
-		}
-#endif
-		skb = dev_alloc_skb((value->len) + 2);
-		ASSERT(skb != NULL, ircomm_do_event(self, QUERYIAS_ERROR, NULL);return;);
-		frame = skb_put(skb,2);
-		/* MSB first */
-		frame[0] = ( value->len >> 8 ) & 0xff;
-		frame[1] = value->len & 0xff;
-		
-		frame = skb_put(skb,value->len);
-		memcpy(frame, value->t.oct_seq, value->len);
-		ircomm_parse_tuples(self, skb, IAS_PARAM);
-		kfree_skb(skb);
-
-		/* 
-		 * check if servicetype we want is available 
-		 */
-
-		DEBUG(0,__FUNCTION__"():peer capability is:\n");
-		DEBUG(0,"3wire raw: %s\n",
-		      ((self->peer_servicetype & THREE_WIRE_RAW) ? "yes":"no"));
-		DEBUG(0,"3wire    : %s\n",
-		      ((self->peer_servicetype & THREE_WIRE) ? "yes":"no"));
-		DEBUG(0,"9wire    : %s\n",
-		      ((self->peer_servicetype & NINE_WIRE) ? "yes":"no"));
-		DEBUG(0,"IEEE1284 : %s\n",
-		      ((self->peer_servicetype & CENTRONICS) ? "yes":"no"));
-
-		self->servicetype &= self->peer_servicetype;
-		if(!(self->servicetype)){
-			DEBUG(0,__FUNCTION__"(): servicetype mismatch!\n");
-			ircomm_do_event(self, QUERYIAS_ERROR, NULL);
-			break;
-		}
-
-		/*
-		 * then choose better one 
-		 */
-		if(self->servicetype & THREE_WIRE_RAW)
-			servicetype = THREE_WIRE_RAW;
-		if(self->servicetype & THREE_WIRE)
-			servicetype = THREE_WIRE;
-		if(self->servicetype & NINE_WIRE)
-			servicetype = NINE_WIRE;
-		if(self->servicetype & CENTRONICS)
-			servicetype = CENTRONICS;
-
-		self->servicetype = servicetype;
-
-		/* enter next state */
-		ircomm_do_event(self, GOT_PARAMETERS, NULL);
-		break;
-
-	case IAS_INTEGER:
-		/* LsapSel seems to be sent to me */	
-		DEBUG(0, __FUNCTION__"():got lsapsel = %d\n", value->t.integer);
-
-		if ( value->t.integer == -1){
-			DEBUG( 0, __FUNCTION__"():invalid value!\n");
-			ircomm_do_event(self, QUERYIAS_ERROR, NULL);
-			return;
-		}
-		self->dlsap = value->t.integer;
-		ircomm_do_event(self, GOT_LSAPSEL, NULL);
-		break;
-
-	case IAS_MISSING:
-		DEBUG( 0, __FUNCTION__":got IAS_MISSING\n");
-		ircomm_do_event(self, QUERYIAS_ERROR, NULL);
-		break;
-   
-	default:
-		DEBUG( 0, __FUNCTION__":got unknown (strange?)type!\n");
-		ircomm_do_event(self, QUERYIAS_ERROR, NULL);
-		break;
-	}
-}
-
-
-
-/* 
- * ----------------------------------------------------------------------
- * Impl. of actions (descrived in section 7.4 of the reference)
- * ----------------------------------------------------------------------
- */
-
-static void issue_connect_request(struct ircomm_cb *self,
-				  struct sk_buff *userdata )
-{
-	/* TODO: we have to send/build userdata field which contains 
-	   InitialControlParameters */
-
-	switch(self->servicetype){
-	case THREE_WIRE_RAW:
-		DEBUG(0, __FUNCTION__"():THREE_WIRE_RAW is not implemented\n");
-		break;
-
-	case DEFAULT: 
-	case THREE_WIRE:
-	case NINE_WIRE:
-	case CENTRONICS:
-
-		irttp_connect_request(self->tsap, self->dlsap, 
-				      self->saddr, self->daddr, 
-				      NULL, self->rx_max_sdu_size, userdata); 
-		break;
-
-	default:
-		printk(KERN_ERR __FUNCTION__"():Illegal servicetype %d\n"
-		       ,self->servicetype);
-	}
-}	
-
-static void disconnect_indication(struct ircomm_cb *self, struct sk_buff *skb)
-{
-
-	/*
-	 * Not implemented parameter"Reason".That is optional.
-	 * What is reason? maybe discribed in irmod.h?
-	 */
-
-	if(self->notify.disconnect_indication)
-		self->notify.disconnect_indication( self->notify.instance,
-						    self,
-						    self->reason, skb);
-						    
-}
-
-static void connect_indication(struct ircomm_cb *self, struct qos_info *qos, 
-			       struct sk_buff *skb)
-{
-
-/* If controlparameters don't exist, we use the servicetype"DEFAULT".*/
-/* 	if( !ircomm_parse_controlchannel( self, data)) */
-/* 		self->servicetype = DEFAULT;     TODOD:fix this! TH */
-
-	if (self->notify.connect_indication)
-		self->notify.connect_indication(self->notify.instance, self, 
-						qos, self->tx_max_sdu_size,
-						self->max_header_size, skb);
-}
-    
-#if 0
-/*   it's for THREE_WIRE_RAW.*/
-static void connect_indication_three_wire_raw(void)
-{ 
-	DEBUG(0,"ircomm:connect_indication_threewire():not implemented!");
-}    
-#endif 
-
-
-static void connect_confirm(struct ircomm_cb *self, struct sk_buff *skb)
-{
-	DEBUG(4 ,__FUNCTION__"()\n");
-
-	/* give a connect_confirm to the client */
-	if( self->notify.connect_confirm )
-		self->notify.connect_confirm(self->notify.instance,
-					     self, NULL, self->tx_max_sdu_size,
-					     self->max_header_size, skb);
-}
-
-static void issue_connect_response(struct ircomm_cb *self,
-				   struct sk_buff *skb)
-{
-	DEBUG(0,__FUNCTION__"()\n");
-	
-	if( self->servicetype == THREE_WIRE_RAW){
-		DEBUG(0,__FUNCTION__"():THREE_WIRE_RAW is not implemented yet\n");
-		/* irlmp_connect_rsp(); */
-	} else
-		irttp_connect_response(self->tsap, self->rx_max_sdu_size, skb);
-}
-
-static void issue_disconnect_request(struct ircomm_cb *self,
-				     struct sk_buff *userdata)
-{
-	if(self->servicetype == THREE_WIRE_RAW){
-		DEBUG(0,__FUNCTION__"():3wireraw is not implemented\n");
-	}
-	else
-		irttp_disconnect_request(self->tsap, userdata, 
-					 self->disconnect_priority);
-}
-    
-static void issue_data_request(struct ircomm_cb *self,
-			       struct sk_buff *userdata )
-{
-	int err;
-
-	if (self->servicetype == THREE_WIRE_RAW){
-		/* irlmp_data_request(self->lmhandle,userdata); */
-		DEBUG(0,__FUNCTION__"():not implemented!");
-		return;
-	}
-
-	DEBUG(4,__FUNCTION__"():sending frame\n");
-	err = irttp_data_request(self->tsap, userdata);
-	if (err){
-		printk(KERN_ERR __FUNCTION__":ttp_data_request failed\n");
-		if (userdata)
-			dev_kfree_skb( userdata);
-	}
-	self->tx_packets++;
-}
-
-static void issue_control_request(struct ircomm_cb *self,
-				  struct sk_buff *userdata)
-{
-	int err;
-
-	DEBUG(4,__FUNCTION__"()\n"); 
-	if (self->servicetype == THREE_WIRE_RAW) {
-		DEBUG(0,__FUNCTION__"():THREE_WIRE_RAW is not implemented\n");
-		
-	}
-	else 
-	{
-		err = irttp_data_request(self->tsap,userdata);
-		if(err)
-		{
-			printk( __FUNCTION__"():ttp_data_request failed\n");
-			if(userdata)
-				dev_kfree_skb(userdata);
-		}
-		else
-			self->tx_controls++;
-
-		self->pending_control_tuples = 0;
-	}
-}
-
-static void process_data(struct ircomm_cb *self, struct sk_buff *skb )
-{
-	
-	DEBUG(4,__FUNCTION__":skb->len=%d, ircomm header = 1, clen=%d\n",
-	      (int)skb->len ,(int)skb->data[0]);
-
-	/* we have to parse control channel when receiving.  (see
-	 * page17 of IrCOMM standard) but it is not parsed here since
-	 * upper layer may have some receive buffer.
-	 *
-	 * hence upper layer have to parse it when it consumes a packet.
-	 *   -- TH
-	 */
-
- 	/* ircomm_parse_control(self, skb, CONTROL_CHANNEL); */
-
-	if (self->notify.data_indication && skb->len)
-		self->notify.data_indication(self->notify.instance, self,
-					     skb);
-}
-
-int ircomm_data_indication(struct ircomm_cb *self, struct sk_buff *skb)
-{
-	/* Not implemented yet:THREE_WIRE_RAW service uses this function.  */
-	DEBUG(0,"ircomm_data_indication:not implemented yet!\n");
-
-	return 0;
-}
-
-
-/* 
- * ----------------------------------------------------------------------
- * Implementation of state chart,
- * descrived in section 7.1 of the specification.
- * ----------------------------------------------------------------------
- */
-
-static void ircomm_do_event( struct ircomm_cb *self, IRCOMM_EVENT event,
-			     struct sk_buff *skb) 
-{
-	
-	DEBUG( 4, __FUNCTION__": STATE = %s, EVENT = %s\n",
-	       ircommstate[self->state], ircommevent[event]);
-	(*state[self->state])(self, event, skb);
-}
-
-static void ircomm_next_state( struct ircomm_cb *self, IRCOMM_STATE state) 
-{
-	self->state = state;
-	DEBUG( 0, __FUNCTION__": NEXT STATE=%d(%s), servicetype=(%d)\n", 
-	       (int)state, ircommstate[self->state],self->servicetype);
-}
-
-
-
-/*
- * ircomm_state_idle
- */
-
-static void ircomm_state_idle( struct ircomm_cb *self, IRCOMM_EVENT event, 
-			       struct sk_buff *skb )
-{
-	switch (event){
-	case IRCOMM_CONNECT_REQUEST:
-
-		/* ircomm_next_state(self, COMM_WAITI); */
-		/* issue_connect_request( self, skb ); */
-
-		ircomm_next_state(self, COMM_DISCOVERY_WAIT);
-		start_discovering(self);
-		break;
-		
-	case TTP_CONNECT_INDICATION:
-
-		ircomm_next_state(self, COMM_WAITR);
-		connect_indication( self, self->qos, skb);
-		break;
-
-	case LMP_CONNECT_INDICATION:
-
-		DEBUG(0,__FUNCTION__"():LMP_CONNECT_IND is notimplemented!");
- 		/* connect_indication_three_wire_raw(); */
- 		/* ircomm_next_state(self, COMM_WAITR); */
-		break;
-
-	default:
-		DEBUG(0,__FUNCTION__"():unknown event =%d(%s)\n",
-		      event, ircommevent[event]);
-	}
-}
-
-/*
- * ircomm_state_discoverywait
- */
-static void ircomm_state_discoverywait(struct ircomm_cb *self, 
-				       IRCOMM_EVENT event, 
-				       struct sk_buff *skb )
-{
-	switch(event){
-
-	case TTP_CONNECT_INDICATION:
-
-		ircomm_next_state(self, COMM_WAITR);
-		queryias_done(self);
-		connect_indication( self, self->qos, skb);
-		break;
-
-	case DISCOVERY_INDICATION:
-		ircomm_next_state(self, COMM_QUERYPARAM_WAIT);
-		query_parameters(self);
-		break;
-
-	case IRCOMM_DISCONNECT_REQUEST:
-		ircomm_next_state(self, COMM_IDLE);
-		queryias_done(self);
-		break;
-
-	case QUERYIAS_ERROR:
-		ircomm_next_state(self, COMM_IDLE);
-		disconnect_indication(self, NULL);
-		queryias_done(self);
-		break;
-
-	default:
-		DEBUG(0,__FUNCTION__"():unknown event =%d(%s)\n",
-		      event, ircommevent[event]);
-	}
-}
-
-/*
- * ircomm_state_queryparamwait
- */
-
-static void ircomm_state_queryparamwait(struct ircomm_cb *self, 
-					IRCOMM_EVENT event, 
-					struct sk_buff *skb)
-{
-	switch (event) {
-	case TTP_CONNECT_INDICATION:
-
-		ircomm_next_state(self, COMM_WAITR);
-		connect_indication( self, self->qos, skb);
-		break;
-
-	case GOT_PARAMETERS:
-		
-		ircomm_next_state(self, COMM_QUERYLSAP_WAIT);
-		query_lsapsel( self );
-		break;
-
-	case IRCOMM_DISCONNECT_REQUEST:
-		ircomm_next_state(self, COMM_IDLE);
-		queryias_done(self);
-		break;
-
-	case QUERYIAS_ERROR:
-		ircomm_next_state(self, COMM_IDLE);
-		disconnect_indication(self, NULL);
-		queryias_done(self);
-		break;
-
-	default:
-		DEBUG(0,__FUNCTION__"():unknown event =%d(%s)\n",
-		      event, ircommevent[event]);
-	}
-}
-
-/*
- * ircomm_state_querylsapwait
- */
-
-static void ircomm_state_querylsapwait(struct ircomm_cb *self, 
-				       IRCOMM_EVENT event, 
-				       struct sk_buff *skb )
-{
-	switch (event) {
-
-	case TTP_CONNECT_INDICATION:
-
-		ircomm_next_state(self, COMM_WAITR);
-		connect_indication( self, self->qos, skb);
-		break;
-
-	case GOT_LSAPSEL:
-		
-		ircomm_next_state(self, COMM_WAITI);
-		queryias_done(self);
-		issue_connect_request( self, skb );
-		break;
-
-	case IRCOMM_DISCONNECT_REQUEST:
-		ircomm_next_state(self, COMM_IDLE);
-		queryias_done(self);
-		break;
-
-	case QUERYIAS_ERROR:
-		ircomm_next_state(self, COMM_IDLE);
-		disconnect_indication(self, NULL);
-		queryias_done(self);
-		break;
-
-
-	default:
-		DEBUG(0,__FUNCTION__"():unknown event =%d(%s)\n",
-		      event, ircommevent[event]);
-	}
-}
-
-/*
- * ircomm_state_waiti
- */
-
-static void ircomm_state_waiti(struct ircomm_cb *self, IRCOMM_EVENT event, 
-			  struct sk_buff *skb )
-{
-	switch (event) {
-	case TTP_CONNECT_CONFIRM:
-		ircomm_next_state(self, COMM_CONN);
-		connect_confirm(self, skb );
-		break;
-	case TTP_DISCONNECT_INDICATION:
-		ircomm_next_state(self, COMM_IDLE);
-		disconnect_indication(self, skb);
-		break;
-/* 	case LMP_CONNECT_CONFIRM: */
-/* 		ircomm_connect_cnfirmation; */
-/* 		ircomm_next_state(self, COMM_CONN); */
-/* 		break; */
-/* 	case LMP_DISCONNECT_INDICATION: */
-/* 		ircomm_disconnect_ind; */
-/* 		ircomm_next_state(self, COMM_IDLE); */
-/* 		break; */
-	default:
-		DEBUG(0,__FUNCTION__"():unknown event =%d(%s)\n",
-		      event, ircommevent[event]);
-	}
-}
-
-/*
- * ircomm_state_waitr
- */
-static void ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event, 
-			       struct sk_buff *skb ) 
-{
-	switch (event) {
-	case IRCOMM_CONNECT_RESPONSE:
-
-	        /* issue_connect_response */
-		
-		if (self->servicetype==THREE_WIRE_RAW) {
-			DEBUG(0,__FUNCTION__"():3WIRE_RAW is not implemented\n");
-			/* irlmp_connect_response(Vpeersap,
-			 *                         ACCEPT,null);
-			 */
-		} else {
-			ircomm_next_state(self, COMM_CONN);
-			issue_connect_response(self, skb);
-		}
-		break;
-
-	case IRCOMM_DISCONNECT_REQUEST:
-		ircomm_next_state(self, COMM_IDLE);
-		issue_disconnect_request(self, skb);
-		queryias_done(self);
-		break;
-
-	case TTP_DISCONNECT_INDICATION:
-		ircomm_next_state(self, COMM_IDLE);
-		disconnect_indication(self, skb);
-		break;
-
-	case DISCOVERY_INDICATION:
-		DEBUG(0, __FUNCTION__"():DISCOVERY_INDICATION\n");
-		queryias_done(self);
-		break;
-	case GOT_PARAMETERS:
-		DEBUG(0, __FUNCTION__"():GOT_PARAMETERS\n");
-		queryias_done(self);
-		break;
-	case GOT_LSAPSEL:
-		DEBUG(0, __FUNCTION__"():GOT_LSAPSEL\n");
-		queryias_done(self);
-		break;
-
-/* 	case LMP_DISCONNECT_INDICATION: */
-/* 		disconnect_indication();		 */
-/* 		ircomm_next_state(self, COMM_IDLE);		 */
-/* 		break; */
-	default:
-		DEBUG(0,"ircomm_state_waitr:unknown event =%d(%s)\n",
-		      event, ircommevent[event]);
-	}
-}
-
-/*
- * ircomm_state_conn
- */
-
-static void ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event, 
-			      struct sk_buff *skb )
-{
-	switch (event) {
-	case TTP_DATA_INDICATION:
-		process_data(self, skb);
-		break;
-	case IRCOMM_DATA_REQUEST:
-		issue_data_request(self, skb);
-		break;
-/* 	case LMP_DATA_INDICATION: */
-/* 		ircomm_data_indicated(); */
-/* 		break; */
-	case IRCOMM_CONTROL_REQUEST:
-		issue_control_request(self, skb);
-		break;
-	case TTP_DISCONNECT_INDICATION:
-		ircomm_next_state(self, COMM_IDLE);
-		disconnect_indication(self, skb);
-		break;
-	case IRCOMM_DISCONNECT_REQUEST:
-		ircomm_next_state(self, COMM_IDLE);
-		issue_disconnect_request(self, skb);
-		queryias_done(self);
-		break;
-/* 	case LM_DISCONNECT_INDICATION: */
-/* 		disconnect_indication(); */
-/* 		ircomm_next_state(self, COMM_IDLE); */
-/* 		break; */
-
-	case DISCOVERY_INDICATION:
-		DEBUG(0, __FUNCTION__"():DISCOVERY_INDICATION\n");
-		queryias_done(self);
-		break;
-	case GOT_PARAMETERS:
-		DEBUG(0, __FUNCTION__"():GOT_PARAMETERS\n");
-		queryias_done(self);
-		break;
-	case GOT_LSAPSEL:
-		DEBUG(0, __FUNCTION__"():GOT_LSAPSEL\n");
-		queryias_done(self);
-		break;
-
-	default:
-		DEBUG(0,"ircomm_state_conn:unknown event =%d(%s)\n",
-		      event, ircommevent[event]);
-	}
-}
-
-/*
- *  ----------------------------------------------------------------------
- *  IrCOMM service interfaces and supporting functions
- *
- *  ----------------------------------------------------------------------
- */
-
-/*
- * Function start_discovering (self)
- *
- *    Start discovering and enter DISCOVERY_WAIT state
- *
- */
-static void start_discovering(struct ircomm_cb *self)
-{
-	__u16  hints; 
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRCOMM_MAGIC, return;);
-	DEBUG(4,__FUNCTION__"():servicetype = %d\n",self->servicetype);
-	
-
-	hints = irlmp_service_to_hint(S_COMM);
-
-	DEBUG(1,__FUNCTION__"():start discovering..\n");
-	switch (ircomm_cs) {
-	case 0:
-		MOD_INC_USE_COUNT;
-		self->queryias_lock = 1;
-		discovering_instance = self;
-		self->skey = irlmp_register_service(hints);
-		self->ckey = irlmp_register_client(hints, ircomm_discovery_indication,
-					     NULL);
-		break;
-		
-	case 1:    /* client only */
-		MOD_INC_USE_COUNT;
-		self->queryias_lock = 1;
-		discovering_instance = self;
-		DEBUG( 0, __FUNCTION__"():client only mode\n");
-		self->ckey = irlmp_register_client(hints, ircomm_discovery_indication,
-					     NULL);
-		break;
-
-	case 2:     /*  server only  */
-	default:
-		DEBUG( 0, __FUNCTION__"():server only mode\n");
-		self->skey = irlmp_register_service(hints);
-		discovering_instance = NULL;
-		break;
-	}
-	
-	return;
-}
-
-/*
- * queryias_done(self)
- *
- * 
- */
-
-/*
- * Function queryias_done (self)
- *
- *    Called when discovery process got wrong results, completed, or
- *    terminated.
- * 
- */
-static void queryias_done(struct ircomm_cb *self)
-{
-	DEBUG(0, __FUNCTION__"():\n");
-	if (self->queryias_lock){
-		self->queryias_lock = 0;
-		discovering_instance = NULL;
-		MOD_DEC_USE_COUNT;
-		irlmp_unregister_client(self->ckey);
-	}
-	if (ircomm_cs != 1)
-		irlmp_unregister_service(self->skey);
-	return;
-}
-
-
-
-static void query_parameters(struct ircomm_cb *self)
-{
-
-	DEBUG(0, __FUNCTION__"():querying IAS: Parameters..\n");
-	iriap_getvaluebyclass_request( "IrDA:IrCOMM", "Parameters",
-				       self->saddr, self->daddr,
-				       ircomm_getvalue_confirm, self );
-}
-
-static void query_lsapsel(struct ircomm_cb * self)
-{
-	DEBUG(0, __FUNCTION__"():querying IAS: Lsapsel...\n");
-
-	if (!(self->servicetype & THREE_WIRE_RAW)) {
-		iriap_getvaluebyclass_request( 
-			"IrDA:IrCOMM", "IrDA:TinyTP:LsapSel",
-			self->saddr, self->daddr,
-			ircomm_getvalue_confirm, self );
-	} else {
-		DEBUG(0, __FUNCTION__ "THREE_WIRE_RAW is not implemented!\n");
-	}
-}
-
-/*
- * Function ircomm_connect_request (self, servicetype)
- *
- *    Impl. of this function is differ from one of the reference. This
- *    function does discovery as well as sending connect request
- * 
- */
-void ircomm_connect_request(struct ircomm_cb *self, __u8 servicetype)
-{
-	/*
-	 * TODO:build a packet which contains "initial control parameters"
-	 * and send it with connect_request
-	 */
-
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRCOMM_MAGIC, return;);
-
-
-	DEBUG(1, __FUNCTION__"():sending connect_request...\n");
-
-	self->servicetype= servicetype;
-	/* ircomm_control_request(self, SERVICETYPE); */ /*servictype*/
-
-	self->rx_max_sdu_size = SAR_DISABLE;
-	ircomm_do_event(self, IRCOMM_CONNECT_REQUEST, NULL);
-}
-
-void ircomm_connect_response(struct ircomm_cb *self, struct sk_buff *userdata,
-			     __u32 max_sdu_size)
-{
-
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRCOMM_MAGIC, return;);
-	/* ASSERT( userdata != NULL, return;); */
-
-	DEBUG(4,"ircomm_connect_response:\n");
-
-	/*
-	 * TODO:build a packet which contains "initial control parameters"
-	 * and send it with connect_response
-	 */
-
-	if (!userdata){
-		/* FIXME: check for errors and initialize? DB */
-		userdata = dev_alloc_skb(COMM_DEFAULT_SDU_SIZE + COMM_MAX_HEADER_SIZE);
-		if (userdata == NULL)
-			return;
-
-		skb_reserve(userdata,COMM_MAX_HEADER_SIZE);
-	}
-
-	/* enable null-modem emulation (i.e. server mode )*/
-	self->null_modem_mode = 1;
-
-	self->rx_max_sdu_size = max_sdu_size;
-	
-	ircomm_do_event(self, IRCOMM_CONNECT_RESPONSE, userdata);
-}	
-
-void ircomm_disconnect_request(struct ircomm_cb *self, 
-			       struct sk_buff *userdata,
-			       int priority)
-{
-
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRCOMM_MAGIC, return;);
-	DEBUG(0,__FUNCTION__"()\n");
-
-#if 0
-	/* unregister layer */
-	switch (ircomm_cs) {
-	case 1:    /* client only */
-		irlmp_unregister_client(ckey);
-		break;
-
-	case 2:     /*  server only  */
-		irlmp_unregister_service(skey);
-		break;
-	case 0:
-	default:
-		irlmp_unregister_client(ckey);
-		irlmp_unregister_service(skey);
-		break;
-	}
-#endif
-
-	self->disconnect_priority = priority;
-	if(priority != P_HIGH)
-		self->disconnect_priority = P_NORMAL;
-
-	ircomm_do_event(self, IRCOMM_DISCONNECT_REQUEST, userdata);
-}	
-
-
-int ircomm_data_request(struct ircomm_cb *self, struct sk_buff *userdata)
-{
-	__u8 * frame;
-
-	DEBUG(4,__FUNCTION__"()\n");
-	ASSERT( self != NULL, return -EFAULT;);
-	ASSERT( self->magic == IRCOMM_MAGIC, return -EFAULT;);
-	ASSERT( userdata != NULL, return -EFAULT;);
-	
-
-	if(self->state != COMM_CONN){
-		DEBUG(4,__FUNCTION__"():not connected, data is ignored\n");
-		return -EINVAL;
-	}
-
-	if(self->ttp_stop)
-		return -EBUSY;
-
-	if(self->control_ch_pending){
-		/* send control_channel */
-		ircomm_tx_controlchannel(self);
-	}
-
-	if(self->ttp_stop)
-		return -EBUSY;
-
-	/* add "clen" field */
-	frame = skb_push(userdata,1);
-	frame[0]=0;          /* without control channel */
-
-	ircomm_do_event(self, IRCOMM_DATA_REQUEST, userdata);
-	return 0;
-}
-
-/*
- *  ----------------------------------------------------------------------
- *  IrCOMM_control.req and friends
- *
- *  ----------------------------------------------------------------------
- */
-
-
-static void ircomm_tx_controlchannel(struct ircomm_cb *self )
-{
-
-	__u8 clen;
-	struct sk_buff *skb = self->ctrl_skb;
-	
-	DEBUG(4,__FUNCTION__"()\n");
-	/* 'self' should have been checked */
-	ASSERT(!self->ttp_stop, return ;);
-	ASSERT(self->state == COMM_CONN, return ;);
-
-	/* add "clen" field */
-
-	clen=skb->len;
-	ASSERT(clen != 0,return;);
-
-	skb_push(skb,1);
-	skb->data[0]=clen;
-
-#if 0
-	printk("tx_ctrl:");
-	{
-		int i;
-		for ( i=0;i<skb->len;i++)
-			printk("%02x", skb->data[i]);
-		printk("\n");
-	}
-#endif
-	
-	ircomm_do_event(self, IRCOMM_CONTROL_REQUEST, skb);
-	self->control_ch_pending = 0;
-
-	skb = dev_alloc_skb(COMM_DEFAULT_SDU_SIZE + COMM_MAX_HEADER_SIZE);
-	ASSERT(skb != NULL, return ;);
-
-	skb_reserve(skb,COMM_MAX_HEADER_SIZE);
-	self->ctrl_skb = skb;
-}
-
-
-static void append_tuple(struct ircomm_cb *self, __u8 instruction, __u8 pl , 
-			 __u8 *value)
-{
-	__u8 *frame;
-	struct sk_buff *skb;
-	int i,c = 0;
-	unsigned long flags;
-
-	save_flags(flags);cli();
-
-	skb = self->ctrl_skb;
-	ASSERT(skb != NULL, return;);
-	
-	if(skb_tailroom(skb) < (pl+2)){
-		DEBUG(0, __FUNCTION__"there's no room.. ignore it\n");
-		self->ignored_control_tuples++;
-		restore_flags(flags);
-		return;
-	}
-
-	frame = skb_put(skb,pl+2);
-	frame[c++] = instruction;     /* PI */
-	frame[c++] = pl;              /* PL */
-	for(i=0; i < pl ; i++)
-		frame[c++] = *value++;   /* PV */
-	restore_flags(flags);	
-	self->pending_control_tuples++;
-	self->control_ch_pending = 1;
-}
-
-/*
- * Function ircomm_control_request (self, instruction)
- *
- *    This function is exported as a request to send some control-channel
- *    tuples * to peer device
- * 
- */
-void ircomm_control_request(struct ircomm_cb *self,  __u8 instruction)
-{
-
-	__u8  pv[32];      /* 32 max, for PORT_NAME */
-	__u8  *value = &pv[0];
-	__u32 temp;
-	int notsupp=0;
-
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRCOMM_MAGIC, return;);
-
-	if(self->servicetype == THREE_WIRE_RAW){
-		DEBUG(0,__FUNCTION__"():THREE_WIRE_RAW shuold not use me!\n");
-		return;
-	}
-
-	DEBUG(4,__FUNCTION__"()\n");
-
-	/* find parameter and its length */
-
-	if(self->servicetype == THREE_WIRE) goto threewire;
-	if(self->servicetype == NINE_WIRE) goto ninewire;
-
-
-	/* FIXME: centronics service is not fully implemented yet*/
-	switch(instruction){
-	case IEEE1284_MODE_SUPPORT:
-	case IEEE1284_DEVICEID:
-		append_tuple(self,instruction,0,NULL);
-		break;
-	case STATUS_QUERY:
-		append_tuple(self,instruction,0,NULL);
-		break;
-	case SET_BUSY_TIMEOUT:
-		value[0] = self->busy_timeout;
-		append_tuple(self,instruction,1,value);
-		break;
- 	case IEEE1284_ECP_EPP_DATA_TRANSFER: 
-		value[0] = self->ecp_epp_mode;
-		value[1] = self->channel_or_addr;
-		append_tuple(self,instruction,2,value); 
-		break; 
-	default:
-		notsupp=1;
-	}
-
- ninewire:
-	switch(instruction){
-	case POLL_FOR_LINE_SETTINGS:
-		append_tuple(self,instruction,0,NULL);
-		break;
-	case DTELINE_STATE:		
-		if(self->null_modem_mode){
-			/* null modem emulation */
-
-			/* output RTS as CTS */
-
-			if(self->dte & DELTA_RTS)
-				value[0] = DELTA_CTS;
-			if(self->dte & MCR_RTS)
-				value[0] |= MSR_CTS;
-
-			/* output DTR as {DSR & CD & RI} */
-
-			if(self->dte & DELTA_DTR)
-				value[0] |= (DELTA_DSR|DELTA_RI|DELTA_DCD);
-			if(self->dte & MCR_DTR)
-				value[0] |= (MSR_DSR|MSR_RI|MSR_DCD);
-			append_tuple(self,DCELINE_STATE,1,value);
-		}else{
-			value[0] = self->dte;
-			append_tuple(self,instruction,1,value);
-		}
-		self->dte &= ~(DELTA_RTS|DELTA_DTR);
-		break;
-
-	case DCELINE_STATE:		
-		value[0] = self->dce;
-		append_tuple(self,instruction,1,value);
-		break;
-
-	default:
-		notsupp=1;
-	}
-
- threewire:
-	switch(instruction){
-
-	case SERVICETYPE:
-		value[0] = self->servicetype;
-		append_tuple(self,instruction,1,value);
-		break;
-
-	case DATA_FORMAT:
-		value[0] = self->data_format;
-		append_tuple(self,instruction,1,value);
-		break;
-
-	case FLOW_CONTROL:
-		if(self->null_modem_mode){
-			/* inside out */
-			value[0]  = (self->flow_ctrl & 0x55) << 1;
-			value[0] |= (self->flow_ctrl & 0xAA) >> 1;
-		}else{
-			value[0] = self->flow_ctrl;
-		}
-		append_tuple(self,instruction,1,value);
-		break;
-
-	case LINESTATUS:
-		value[0] = self->line_status;
-		append_tuple(self,instruction,1,value);
-		break;
-
-	case BREAK_SIGNAL:
-		value[0] = self->break_signal;
-		append_tuple(self,instruction,1,value);
-		break;
-
-	case XON_XOFF_CHAR:
-		value[0] = self->xon_char;
-		value[1] = self->xoff_char;
-		append_tuple(self,instruction,2,value); 
-		break; 
-
-	case ENQ_ACK_CHAR:
-		value[0] = self->enq_char;
-		value[1] = self->ack_char;
-		append_tuple(self,instruction,2,value); 
-		break; 
-
-	case DATA_RATE:
-		temp = self->data_rate;
-		value[3] = (__u8)((temp >> 24) & 0x000000ff);
-		value[2] = (__u8)((temp >> 16) & 0x000000ff);
-		value[1] = (__u8)((temp >> 8) & 0x000000ff);
-		value[0] = (__u8)(temp & 0x000000ff);
- 		append_tuple(self,instruction,4,value);
- 		break;
-#if 0
-	case PORT_NAME:
-	case FIXED_PORT_NAME:
-		temp = strlen(&self->port_name);
-		if(temp < 32){
-			value = (__u8) (self->port_name);
-			append_tuple(self,instruction,temp,value);
-		}else
-			DEBUG(0,__FUNCTION__"() PORT_NAME:too long\n");
-#endif
-		break;
-
-	default:
-		if(notsupp)
-			DEBUG(0,__FUNCTION__"():instruction(0x%02x)is not"
-			      "implemented\n",instruction);
-	}
-
-
-}
-
-void ircomm_parse_tuples(struct ircomm_cb *self, struct sk_buff *skb, int type)
-{
-
-	__u8 *data;
-	__u8 pi,plen;
-	int clen = 0;
-	int indicate=0;
-
-	ASSERT(skb != NULL, return;);
-	ASSERT(self != NULL, return ;);
-	ASSERT(self->magic == IRCOMM_MAGIC, return ;);
-
-
-#ifdef IRCOMM_DEBUG_TUPLE
-	DEBUG(0, __FUNCTION__"():tuple sequence is:\n");
-	{
-		int i;
-		for ( i=0;i< skb->len;i++)
-			printk("%02x", (__u8)(skb->data[i]));
-		printk("\n");
-	}
-#endif
-
-	data = skb->data;
-	if(type == IAS_PARAM)
-	{
-		clen = (data[0] << 8) & 0xff00;
-		clen |= data[1] & 0x00ff;
-		ASSERT( clen <= (skb->len - 2) && clen <= 1024, goto corrupted;);
-		DEBUG(4, __FUNCTION__"():IAS_PARAM len = %d\n",clen );
-		skb_pull( skb, 2);
-	}
-	else
-	{
-		/* CONTROL_CHANNEL */
-		clen = data[0];
-		ASSERT( clen < skb->len, goto corrupted;);
-		DEBUG(4, __FUNCTION__"():CONTROL_CHANNEL:len = %d\n",clen );
-		skb_pull( skb, 1);
-	}
-
-	while( clen >= 2 ){
-		data = skb->data;
-		indicate = 0;
-
-		/* 
-		 * parse controlparameters and set value into structure 
-		 */
-		pi = data[0];
-		plen = data[1];
-
-		ASSERT( clen >= 2+plen, goto corrupted; );
-		DEBUG(4, __FUNCTION__"():instruction=0x%02x,len=%d\n",
-		      pi, plen) ;
-
-
-		switch(pi)
-		{
-		case POLL_FOR_LINE_SETTINGS:
-			ircomm_control_request(self, DTELINE_STATE);
-			break;
-		
-		case SERVICETYPE:
-			self->peer_servicetype = data[2];
-			break;
-
-		case PORT_TYPE:
-			self->peer_port_type = data[2];
-			break;
-
-		case DATA_FORMAT:   
-			self->peer_data_format = data[2];
-			break;
-
-		case FLOW_CONTROL:
-			self->peer_flow_ctrl = data[2];
-			indicate = 1;
-			break;
-
-		case LINESTATUS:
-			self->peer_line_status = data[2];
-			indicate = 1;
-			break;
-
-		case BREAK_SIGNAL:
-			self->peer_break_signal = data[2];
-			/* indicate = 1; */
-			break;
-
-		case DCELINE_STATE:
-			self->peer_dce = data[2];
-			indicate = 1;
-			break;
-
-		case DTELINE_STATE:
-			if(self->null_modem_mode){
-				/* input DTR as {DSR & CD & RI} */
-				self->peer_dce = 0;
-				if(data[2] & DELTA_DTR)
-					self->peer_dce |= (DELTA_DSR|
-							   DELTA_RI|
-							   DELTA_DCD);
-				if(data[2] & MCR_DTR)
-					self->peer_dce |= (MSR_DSR|
-							   MSR_RI|
-							   MSR_DCD);
-				/* rts as cts */
-				if(data[2] & DELTA_RTS)
-					self->peer_dce |= DELTA_CTS;
-				if(data[2] & MCR_RTS)
-					self->peer_dce |= MSR_CTS;
-			}else{
-				self->peer_dte = data[2];
-			}
-			indicate = 1;			
-			break;
-			
-		case XON_XOFF_CHAR:
-			self->peer_xon_char = data[2];
-			self->peer_xoff_char = data[3];
-			indicate = 1;
-			break;
-
-		case ENQ_ACK_CHAR:
-			self->peer_enq_char = data[2];
-			self->peer_ack_char = data[3];
-			indicate = 1;
-			break;
-
-		case DATA_RATE:
-			self->peer_data_rate = (  data[5]<<24
-						  & data[4]<<16
-						  & data[3]<<8
-						  & data[2]);
-			indicate = 1;
-			break;
-
-		case PORT_NAME:
-			ASSERT(plen <= 32 , goto corrupted;);
-			memcpy(self->port_name, data + 2, plen);
-			*(__u8 *)(self->port_name+plen) = 0;
-			break;
-
-		case FIXED_PORT_NAME:
-			ASSERT(plen <= 32 , goto corrupted;);
-			memcpy(self->port_name, data + 2, plen);
-			*(__u8 *)(self->port_name+plen) = 0;
-			/* 
-			 * We should not connect if user of IrCOMM can't
-			 * recognize the port name
-			 */
-			self->port_name_critical = TRUE;
-			break;
-
-		default:
-			DEBUG(0, __FUNCTION__
-			      "():not implemented (PI=%d)\n", pi);
-		}
-
-
-		if(indicate && 
-		   self->notify.flow_indication && type == CONTROL_CHANNEL)
-		{
-			DEBUG(4,__FUNCTION__":indicating..:\n");
-			self->pi = pi;
-			if(self->notify.flow_indication)
-				self->notify.flow_indication(self->notify.instance,
-							     self,
-							     CONTROL_CHANNEL);
-		}
-		skb_pull(skb, 2+plen);
-		clen -= (2+plen);
-	}
-
-	return;
-
- corrupted:
-	skb_pull(skb, skb->len);   /* remove suspicious data */
-	return;
-}
-
-/*
- * ----------------------------------------------------------------------
- * Function ircomm_open_instance() ,ircomm_close_instance() and friends
- *
- * ircomm_open_instance discoveres the peer device and then issues a
- * connect request
- * ----------------------------------------------------------------------
- */
-
-
-
-struct ircomm_cb * ircomm_open_instance( struct notify_t client_notify)
-{
-	int i;
-	struct ircomm_cb *self = NULL;
-	struct notify_t notify;
-	unsigned long flags;
-
-	ASSERT(ircomm != NULL,return NULL;);
-	DEBUG(0,__FUNCTION__"():\n");
-
-	/* find free handle */
-
-	save_flags(flags);
-	cli();
-	for(i = 0; i < IRCOMM_MAX_CONNECTION; i++){
-		ASSERT(ircomm[i] != NULL,return(NULL););
-		if(!ircomm[i]->in_use){
-			self = ircomm[i];
-			break;
-		}
-	}
-
-	if (!self){
-		DEBUG(0,__FUNCTION__"():no free handle!\n");
-		return (NULL);
-	}
-
-	self->in_use = 1;
-	restore_flags(flags);
-
-	self->notify = client_notify;
-	self->ttp_stop = 0;
-	self->control_ch_pending = 0;
-
-	/* register callbacks */
-
-	irda_notify_init(&notify);
-	notify.data_indication = ircomm_accept_data_indication;
-	notify.connect_confirm = ircomm_accept_connect_confirm;
-	notify.connect_indication = ircomm_accept_connect_indication;
-	notify.flow_indication = ircomm_accept_flow_indication;
-	notify.disconnect_indication = ircomm_accept_disconnect_indication;
-	notify.instance = self;
-	strncpy( notify.name, "IrCOMM", NOTIFY_MAX_NAME);
-
-	self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT,
-				     &notify);
-	if(!self->tsap){
-		DEBUG(0,__FUNCTION__"failed to allocate tsap\n");
-		return NULL;
-	}
-
-	ircomm_next_state(self, COMM_IDLE);	
-	return (self);
-}
-
-int ircomm_close_instance(struct ircomm_cb *self)
-{
-	ASSERT( self != NULL, return -EIO;);
-	ASSERT( self->magic == IRCOMM_MAGIC, return -EIO;);
-	ASSERT( self->ctrl_skb != NULL, return -EIO;);
-
-	DEBUG(0,__FUNCTION__"()\n");
-
-	/* shutdown ircomm layer */
-	if(self->state != COMM_IDLE && self->state != COMM_WAITI)
-	{
-		DEBUG(0,__FUNCTION__"():force disconnecting..\n");
-		ircomm_disconnect_request(self, NULL, P_HIGH);
-	}
-
-	skb_trim(self->ctrl_skb,0);
-	/* remove a tsap */
-	if(self->tsap)
-		irttp_close_tsap(self->tsap);
-	self->tsap = NULL;
-	self->in_use = 0;
-	return 0;
-}
-
-
-/*
- * ----------------------------------------------------------------------
- * Function init_module(void) ,cleanup_module()
- *
- *   Initializes the ircomm control structure
- *   These Function are called when you insmod / rmmod .
- * ----------------------------------------------------------------------
- */
-
-#ifdef MODULE
-int init_module(void) 
-{
-	int err;
-
-	err = ircomm_init();
-
-	DEBUG( 4, __FUNCTION__"():done.\n");
-	return err;
-}
-	
-void cleanup_module(void)
-{
-	ircomm_cleanup();
-	DEBUG( 4, __FUNCTION__"():done.\n");
-}
-#endif /* MODULE */
-
-/************************************************************
- *     proc stuff
- ************************************************************/
-
-#ifdef CONFIG_PROC_FS
-
-/*
- * Function proc_ircomm_read (buf, start, offset, len, unused)
- *
- * this function is called if there is a access on /proc/irda/comm .
- *
- */
-int ircomm_proc_read(char *buf, char **start, off_t offset,
-		     int len, int unused)
-{
-	int i, index;
-
-	len = 0;
-	for (i=0; i<IRCOMM_MAX_CONNECTION; i++) {
-
-		len += sprintf(buf+len, "instance %d:\n",i);
-		if(ircomm[i]->in_use == 0){
-			len += sprintf(buf+len, "\tunused\n");
-			continue;
-		}
-
-		if (ircomm[i] == NULL || ircomm[i]->magic != IRCOMM_MAGIC) {
-			len += sprintf(buf+len, "\tbroken???\n");
-			continue;
-		}
-
-		switch (ircomm[i]->servicetype) {
-		case UNKNOWN:
-			index = 0;
-			break;
-		case THREE_WIRE_RAW:
-			index = 1;
-			break;
-		case THREE_WIRE:
-			index = 2;
-			break;
-		case NINE_WIRE:
-			index = 3;
-			break;
-		case CENTRONICS:
-			index = 4;
-			break;
-		default:
-			index = 0;
-			break;
-		}
-		len += sprintf(buf+len, "    service: %s  ",
-			       ircommservicetype[index]);
-		if(!index)
-			continue;
-
-		len += sprintf(buf+len, "porttype: %s  ",
-			       ircommporttype[ircomm[i]->port_type]);
-		len += sprintf(buf+len, "state: %s  ",
-			       ircommstate[ircomm[i]->state]);
-		len += sprintf(buf+len, "user: %s\n",
-			       ircomm[i]->notify.name);
-		
-		len += sprintf(buf+len, "    tx packets: %d  ",
-			       ircomm[i]->tx_packets);
-		len += sprintf(buf+len, "rx packets: %d  ",
-			       ircomm[i]->rx_packets);
-		len += sprintf(buf+len, "tx controls: %d\n",
-			       ircomm[i]->tx_controls);
-		
-		len += sprintf(buf+len, "    pending tuples: %d  ",
-			       ircomm[i]->pending_control_tuples);
-		len += sprintf(buf+len, "    ignored tuples: %d\n",
-			       ircomm[i]->ignored_control_tuples);
-		
-		len += sprintf(buf+len, "    nullmodem emulation: %s  ",
-			       (ircomm[i]->null_modem_mode ? "yes":"no"));
-		len += sprintf(buf+len, "IrTTP: %s\n",
-			       (ircomm[i]->ttp_stop ? "BUSY":"READY"));
-
-		len += sprintf(buf+len, "    Peer capability: ");
-		if(ircomm[i]->peer_cap & THREE_WIRE_RAW)
-			len += sprintf(buf+len, "3wire-raw ");
-		if(ircomm[i]->peer_cap & THREE_WIRE)
-			len += sprintf(buf+len, "3wire ");
-		if(ircomm[i]->peer_cap & NINE_WIRE)
-			len += sprintf(buf+len, "9wire ");
-		if(ircomm[i]->peer_cap & CENTRONICS)
-			len += sprintf(buf+len, "centronics");
-
-		len += sprintf(buf+len, "\n    Port name: %s\n",
-			       (ircomm[i]->port_name));
-	}
-
-	return len;
-}
-
-#endif /* CONFIG_PROC_FS */
-
-
-
-

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)