patch-2.2.3 linux/net/irda/irlap.c
Next file: linux/net/irda/irlap_comp.c
Previous file: linux/net/irda/irlan/irlan_srv_event.c
Back to the patch index
Back to the overall index
- Lines: 485
- Date:
Sun Mar 7 15:26:44 1999
- Orig file:
v2.2.2/linux/net/irda/irlap.c
- Orig date:
Wed Jan 20 23:14:07 1999
diff -u --recursive --new-file v2.2.2/linux/net/irda/irlap.c linux/net/irda/irlap.c
@@ -1,12 +1,12 @@
/*********************************************************************
*
* Filename: irlap.c
- * Version: 0.8
+ * Version: 0.9
* Description: An IrDA LAP driver for Linux
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Mon Aug 4 20:40:53 1997
- * Modified at: Sat Jan 16 22:19:27 1999
+ * Modified at: Sat Feb 20 01:39:58 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>,
@@ -43,12 +43,23 @@
#include <net/irda/irlap_comp.h>
hashbin_t *irlap = NULL;
+int sysctl_slot_timeout = SLOT_TIMEOUT;
static void __irlap_close( struct irlap_cb *self);
+static char *lap_reasons[] = {
+ "ERROR, NOT USED",
+ "LAP_DISC_INDICATION",
+ "LAP_NO_RESPONSE",
+ "LAP_RESET_INDICATION",
+ "LAP_FOUND_NONE",
+ "LAP_MEDIA_BUSY",
+ "LAP_PRIMARY_CONFLICT",
+ "ERROR, NOT USED",
+};
+
#ifdef CONFIG_PROC_FS
-int irlap_proc_read( char *buf, char **start, off_t offset, int len,
- int unused);
+int irlap_proc_read( char *, char **, off_t, int, int);
#endif /* CONFIG_PROC_FS */
@@ -138,8 +149,6 @@
irlmp_register_irlap( self, self->saddr, &self->notify);
- DEBUG( 4, "irlap_open -->\n");
-
return self;
}
@@ -166,7 +175,7 @@
irlap_flush_all_queues( self);
self->irdev = NULL;
- self->magic = ~LAP_MAGIC;
+ self->magic = 0;
kfree( self);
}
@@ -194,7 +203,7 @@
/* Be sure that we manage to remove ourself from the hash */
lap = hashbin_remove( irlap, self->saddr, NULL);
if ( !lap) {
- DEBUG( 0, __FUNCTION__ "(), Didn't find myself!\n");
+ DEBUG( 1, __FUNCTION__ "(), Didn't find myself!\n");
return;
}
__irlap_close( lap);
@@ -206,17 +215,17 @@
* Another device is attempting to make a connection
*
*/
-void irlap_connect_indication( struct irlap_cb *self, struct sk_buff *skb)
+void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb)
{
- DEBUG( 4, __FUNCTION__ "()\n");
+ DEBUG(4, __FUNCTION__ "()\n");
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == LAP_MAGIC, return;);
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == LAP_MAGIC, return;);
- irlap_init_qos_capabilities( self, NULL); /* No user QoS! */
+ irlap_init_qos_capabilities(self, NULL); /* No user QoS! */
- irlmp_link_connect_indication( self->notify.instance, &self->qos_tx,
- skb);
+ irlmp_link_connect_indication(self->notify.instance, self->saddr,
+ self->daddr, &self->qos_tx, skb);
}
/*
@@ -247,21 +256,17 @@
ASSERT( self->magic == LAP_MAGIC, return;);
self->daddr = daddr;
-
+
/*
* If the service user specifies QoS values for this connection,
* then use them
*/
irlap_init_qos_capabilities( self, qos_user);
- if ( self->state == LAP_NDM) {
+ if ( self->state == LAP_NDM)
irlap_do_event( self, CONNECT_REQUEST, NULL, NULL);
- } else {
- DEBUG( 0, __FUNCTION__ "() Wrong state!\n");
-
- irlap_disconnect_indication( self, LAP_MEDIA_BUSY);
- }
-
+ else
+ self->connect_pending = TRUE;
}
/*
@@ -302,12 +307,11 @@
if ( self->qos_tx.compression.value) {
skb = irlap_decompress_frame( self, skb);
if ( !skb) {
- DEBUG( 0, __FUNCTION__ "(), Decompress error!\n");
+ DEBUG( 1, __FUNCTION__ "(), Decompress error!\n");
return;
}
}
#endif
-
irlmp_link_data_indication( self->notify.instance, LAP_RELIABLE, skb);
}
@@ -319,7 +323,7 @@
*/
void irlap_unit_data_indication( struct irlap_cb *self, struct sk_buff *skb)
{
- DEBUG( 0, __FUNCTION__ "()\n");
+ DEBUG( 1, __FUNCTION__ "()\n");
ASSERT( self != NULL, return;);
ASSERT( self->magic == LAP_MAGIC, return;);
@@ -333,7 +337,7 @@
skb = irlap_decompress_frame( self, skb);
if ( !skb) {
- DEBUG( 0, __FUNCTION__ "(), Decompress error!\n");
+ DEBUG( 1, __FUNCTION__ "(), Decompress error!\n");
return;
}
}
@@ -356,14 +360,14 @@
ASSERT( self->magic == LAP_MAGIC, return;);
ASSERT( skb != NULL, return;);
- DEBUG( 4, "irlap_data_request: tx_list=%d\n",
+ DEBUG( 4, __FUNCTION__ "(), tx_list=%d\n",
skb_queue_len( &self->tx_list));
#ifdef CONFIG_IRDA_COMPRESSION
if ( self->qos_tx.compression.value) {
skb = irlap_compress_frame( self, skb);
if ( !skb) {
- DEBUG( 0, __FUNCTION__ "(), Compress error!\n");
+ DEBUG( 1, __FUNCTION__ "(), Compress error!\n");
return;
}
}
@@ -401,8 +405,7 @@
}
irlap_do_event( self, SEND_I_CMD, skb, NULL);
} else
- skb_queue_tail( &self->tx_list, skb);
-
+ skb_queue_tail( &self->tx_list, skb);
}
/*
@@ -410,14 +413,26 @@
*
* Request to disconnect connection by service user
*/
-void irlap_disconnect_request( struct irlap_cb *self)
+void irlap_disconnect_request(struct irlap_cb *self)
{
- DEBUG( 4, __FUNCTION__ "()\n");
+ DEBUG(3, __FUNCTION__ "()\n");
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == LAP_MAGIC, return;);
-
- irlap_do_event( self, DISCONNECT_REQUEST, NULL, NULL);
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == LAP_MAGIC, return;);
+
+ switch (self->state) {
+ case LAP_XMIT_P: /* FALLTROUGH */
+ case LAP_XMIT_S: /* FALLTROUGH */
+ case LAP_CONN: /* FALLTROUGH */
+ case LAP_RESET_WAIT: /* FALLTROUGH */
+ case LAP_RESET_CHECK:
+ irlap_do_event(self, DISCONNECT_REQUEST, NULL, NULL);
+ break;
+ default:
+ DEBUG(0, __FUNCTION__ "(), disconnect pending!\n");
+ self->disconnect_pending = TRUE;
+ break;
+ }
}
/*
@@ -428,7 +443,7 @@
*/
void irlap_disconnect_indication( struct irlap_cb *self, LAP_REASON reason)
{
- DEBUG( 4, __FUNCTION__ "()\n");
+ DEBUG( 1, __FUNCTION__ "(), reason=%s\n", lap_reasons[reason]);
ASSERT( self != NULL, return;);
ASSERT( self->magic == LAP_MAGIC, return;);
@@ -442,18 +457,18 @@
switch( reason) {
case LAP_RESET_INDICATION:
- DEBUG( 0, "Sending reset request!\n");
+ DEBUG( 1, __FUNCTION__ "(), Sending reset request!\n");
irlap_do_event( self, RESET_REQUEST, NULL, NULL);
break;
- case LAP_NO_RESPONSE:
- case LAP_DISC_INDICATION:
- case LAP_FOUND_NONE:
+ case LAP_NO_RESPONSE: /* FALLTROUGH */
+ case LAP_DISC_INDICATION: /* FALLTROUGH */
+ case LAP_FOUND_NONE: /* FALLTROUGH */
case LAP_MEDIA_BUSY:
irlmp_link_disconnect_indication( self->notify.instance,
self, reason, NULL);
break;
default:
- DEBUG( 0, __FUNCTION__ "(), Reason %d not implemented!\n",
+ DEBUG( 1, __FUNCTION__ "(), Reason %d not implemented!\n",
reason);
}
}
@@ -471,24 +486,48 @@
ASSERT( self != NULL, return;);
ASSERT( self->magic == LAP_MAGIC, return;);
ASSERT( discovery != NULL, return;);
+
+ DEBUG( 4, __FUNCTION__ "(), nslots = %d\n", discovery->nslots);
+ ASSERT(( discovery->nslots == 1) || ( discovery->nslots == 6) ||
+ ( discovery->nslots == 8) || ( discovery->nslots == 16),
+ return;);
+
/*
* Discovery is only possible in NDM mode
*/
if ( self->state == LAP_NDM) {
ASSERT( self->discovery_log == NULL, return;);
self->discovery_log= hashbin_new( HB_LOCAL);
-
- info.S = 6; /* Number of slots */
+
+ info.S = discovery->nslots; /* Number of slots */
info.s = 0; /* Current slot */
-
+
self->discovery_cmd = discovery;
info.discovery = discovery;
+ /* Check if the slot timeout is within limits */
+ if ( sysctl_slot_timeout < 2) {
+ DEBUG( 1, __FUNCTION__
+ "(), to low value for slot timeout!\n");
+ sysctl_slot_timeout = 2;
+ }
+ /*
+ * Highest value is actually 8, but we allow higher since
+ * some devices seems to require it.
+ */
+ if ( sysctl_slot_timeout > 16) {
+ DEBUG( 1, __FUNCTION__
+ "(), to high value for slot timeout!\n");
+ sysctl_slot_timeout = 16;
+ }
+
+ self->slot_timeout = sysctl_slot_timeout;
+
irlap_do_event( self, DISCOVERY_REQUEST, NULL, &info);
} else {
DEBUG( 4, __FUNCTION__
- "(), discovery only possible in NDM mode\n");
+ "(), discovery only possible in NDM mode\n");
irlap_discovery_confirm( self, NULL);
}
}
@@ -506,6 +545,14 @@
ASSERT( self->notify.instance != NULL, return;);
+ /*
+ * Check for successful discovery, since we are then allowed to clear
+ * the media busy condition (irlap p.94). This should allow us to make
+ * connection attempts much easier.
+ */
+ if (discovery_log && hashbin_get_size(discovery_log) > 0)
+ irda_device_set_media_busy(self->irdev, FALSE);
+
/* Inform IrLMP */
irlmp_link_discovery_confirm( self->notify.instance, discovery_log);
@@ -552,7 +599,6 @@
default:
break;
}
- /* TODO: layering violation! */
irlmp_status_indication( quality_of_link, NO_CHANGE);
}
@@ -564,7 +610,7 @@
*/
void irlap_reset_indication( struct irlap_cb *self)
{
- DEBUG( 0, __FUNCTION__ "()\n");
+ DEBUG( 1, __FUNCTION__ "()\n");
ASSERT( self != NULL, return;);
ASSERT( self->magic == LAP_MAGIC, return;);
@@ -583,7 +629,7 @@
*/
void irlap_reset_confirm(void)
{
- DEBUG( 0, __FUNCTION__ "()\n");
+ DEBUG( 1, __FUNCTION__ "()\n");
}
/*
@@ -672,7 +718,7 @@
/* ns as expected? */
if ( ns == self->vr) {
- DEBUG( 4, "*** irlap_validate_ns_received: expected!\n");
+ DEBUG( 4, __FUNCTION__ "(), expected!\n");
return NS_EXPECTED;
}
/*
@@ -696,7 +742,7 @@
/* nr as expected? */
if ( nr == self->vs) {
- DEBUG( 4, "*** irlap_validate_nr_received: expected!\n");
+ DEBUG( 4, __FUNCTION__ "(), expected!\n");
return NR_EXPECTED;
}
@@ -724,7 +770,7 @@
*/
void irlap_initiate_connection_state( struct irlap_cb *self)
{
- DEBUG( 4, "irlap_initiate_connection_state()\n");
+ DEBUG( 4, __FUNCTION__ "()\n");
ASSERT( self != NULL, return;);
ASSERT( self->magic == LAP_MAGIC, return;);
@@ -818,26 +864,26 @@
* Change the speed of the IrDA port
*
*/
-void irlap_change_speed( struct irlap_cb *self, int speed)
+void irlap_change_speed(struct irlap_cb *self, int speed)
{
- DEBUG( 4, __FUNCTION__ "(), setting speed to %d\n", speed);
+ DEBUG(4, __FUNCTION__ "(), setting speed to %d\n", speed);
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == LAP_MAGIC, return;);
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == LAP_MAGIC, return;);
- if ( !self->irdev) {
- DEBUG( 0, __FUNCTION__ "(), driver missing!\n");
+ if (!self->irdev) {
+ DEBUG( 1, __FUNCTION__ "(), driver missing!\n");
return;
}
- irda_device_change_speed( self->irdev, speed);
+ irda_device_change_speed(self->irdev, speed);
self->qos_rx.baud_rate.value = speed;
self->qos_tx.baud_rate.value = speed;
}
#ifdef CONFIG_IRDA_COMPRESSION
-void irlap_init_comp_qos_capabilities( struct irlap_cb *self)
+void irlap_init_comp_qos_capabilities(struct irlap_cb *self)
{
struct irda_compressor *comp;
__u8 mask; /* Current bit tested */
@@ -888,8 +934,8 @@
* IrLAP itself. Normally, IrLAP will not specify any values, but it can
* be used to restrict certain values.
*/
-void irlap_init_qos_capabilities( struct irlap_cb *self,
- struct qos_info *qos_user)
+void irlap_init_qos_capabilities(struct irlap_cb *self,
+ struct qos_info *qos_user)
{
ASSERT( self != NULL, return;);
ASSERT( self->magic == LAP_MAGIC, return;);
@@ -911,8 +957,8 @@
* allowed to supply these values. We check each parameter since the
* user may not have set all of them.
*/
- if ( qos_user != NULL) {
- DEBUG( 0, __FUNCTION__ "(), Found user specified QoS!\n");
+ if (qos_user) {
+ DEBUG( 1, __FUNCTION__ "(), Found user specified QoS!\n");
if ( qos_user->baud_rate.bits)
self->qos_rx.baud_rate.bits &= qos_user->baud_rate.bits;
@@ -966,6 +1012,7 @@
self->bofs_count = 11;
/* Use these until connection has been made */
+ self->slot_timeout = sysctl_slot_timeout;
self->final_timeout = FINAL_TIMEOUT;
self->poll_timeout = POLL_TIMEOUT;
self->wd_timeout = WD_TIMEOUT;
@@ -974,6 +1021,8 @@
self->qos_tx.additional_bofs.value = 11;
irlap_flush_all_queues( self);
+
+ self->disconnect_pending = FALSE;
}
/*
@@ -982,8 +1031,8 @@
* Initialize IrLAP with the negotiated QoS values
*
*/
-void irlap_apply_connection_parameters( struct irlap_cb *self,
- struct qos_info *qos)
+void irlap_apply_connection_parameters(struct irlap_cb *self,
+ struct qos_info *qos)
{
DEBUG( 4, __FUNCTION__ "()\n");
@@ -1010,15 +1059,13 @@
* TODO: these values should be calculated from the final timer
* as well
*/
- if ( qos->link_disc_time.value == 3)
+ if (qos->link_disc_time.value == 3)
self->N1 = 0;
else
- /* self->N1 = 6; */
self->N1 = 3000 / qos->max_turn_time.value;
DEBUG( 4, "Setting N1 = %d\n", self->N1);
- /* self->N2 = qos->link_disc_time.value * 2; */
self->N2 = qos->link_disc_time.value * 1000 / qos->max_turn_time.value;
DEBUG( 4, "Setting N2 = %d\n", self->N2);
@@ -1033,7 +1080,7 @@
#ifdef CONFIG_IRDA_COMPRESSION
if ( qos->compression.value) {
- DEBUG( 0, __FUNCTION__ "(), Initializing compression\n");
+ DEBUG( 1, __FUNCTION__ "(), Initializing compression\n");
irda_set_compression( self, qos->compression.value);
irlap_compressor_init( self, 0);
@@ -1065,7 +1112,7 @@
ASSERT( self != NULL, return -ENODEV;);
ASSERT( self->magic == LAP_MAGIC, return -EBADR;);
- len += sprintf( buf+len, "IrLAP[%d] <-> %s ",
+ len += sprintf( buf+len, "irlap%d <-> %s ",
i++, self->irdev->name);
len += sprintf( buf+len, "state: %s\n",
irlap_state[ self->state]);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)