]> git.neil.brown.name Git - history.git/commitdiff
IrDA update 3/3:
authorJean Tourrilhes <jt@hpl.hp.com>
Sat, 11 May 2002 00:49:24 +0000 (20:49 -0400)
committerJeff Garzik <jgarzik@mandrakesoft.com>
Sat, 11 May 2002 00:49:24 +0000 (20:49 -0400)
 <Following patch from Christoph Bartelmus, mangled by me>
o [CORRECT] replace the global LSAP cache with LSAP caches private
to each LAP.
Fix a bug where two simultaneous connections from two devices
using the same LSAPs would get mixed up.
Should also improve performance in similar cases.

include/net/irda/irlmp.h
net/irda/irlmp.c
net/irda/irlmp_frame.c

index 61360f498cc2159ccb470845c1fa9570c464036c..fdbf5f75ae8506803d7eb51e26bee4f40947955d 100644 (file)
@@ -119,6 +119,21 @@ struct lsap_cb {
        struct lap_cb *lap; /* Pointer to LAP connection structure */
 };
 
+/*
+ *  Used for caching the last slsap->dlsap->handle mapping
+ *
+ * We don't need to keep/match the remote address in the cache because
+ * we are associated with a specific LAP (which implies it).
+ * Jean II
+ */
+typedef struct {
+       int valid;
+
+       __u8 slsap_sel;
+       __u8 dlsap_sel;
+       struct lsap_cb *lsap;
+} CACHE_ENTRY;
+
 /*
  *  Information about each registred IrLAP layer
  */
@@ -140,19 +155,15 @@ struct lap_cb {
        
        struct qos_info *qos;  /* LAP QoS for this session */
        struct timer_list idle_timer;
+       
+#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
+       /* The lsap cache was moved from struct irlmp_cb to here because
+        * it must be associated with the specific LAP. Also, this
+        * improves performance. - Jean II */
+       CACHE_ENTRY cache;  /* Caching last slsap->dlsap->handle mapping */
+#endif
 };
 
-/*
- *  Used for caching the last slsap->dlsap->handle mapping
- */
-typedef struct {
-       int valid;
-
-       __u8 slsap_sel;
-       __u8 dlsap_sel;
-       struct lsap_cb *lsap;
-} CACHE_ENTRY;
-
 /*
  *  Main structure for IrLMP
  */
@@ -166,9 +177,6 @@ struct irlmp_cb {
 
        int free_lsap_sel;
 
-#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
-       CACHE_ENTRY cache;  /* Caching last slsap->dlsap->handle mapping */
-#endif
        struct timer_list discovery_timer;
 
        hashbin_t *links;         /* IrLAP connection table */
index 65a6ed067ef8da601fac237a0d9f4959a08a181f..27a158986350091d73b7f3f6bcb0147ed0ed5124 100644 (file)
@@ -93,9 +93,6 @@ int __init irlmp_init(void)
        irlmp->cachelog = hashbin_new(HB_GLOBAL);
        
        irlmp->free_lsap_sel = 0x10; /* Reserved 0x00-0x0f */
-#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
-       irlmp->cache.valid = FALSE;
-#endif
        strcpy(sysctl_devname, "Linux");
        
        /* Do discovery every 3 seconds */
@@ -208,10 +205,6 @@ static void __irlmp_close_lsap(struct lsap_cb *self)
        if (self->conn_skb)
                dev_kfree_skb(self->conn_skb);
 
-#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
-       ASSERT(irlmp != NULL, return;);
-       irlmp->cache.valid = FALSE;
-#endif
        kfree(self);
 }
 
@@ -247,6 +240,9 @@ void irlmp_close_lsap(struct lsap_cb *self)
                }
                /* Now, remove from the link */
                lsap = hashbin_remove(lap->lsaps, (int) self, NULL);
+#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
+               lap->cache.valid = FALSE;
+#endif
        }
        self->lap = NULL;
        /* Check if we found the LSAP! If not then try the unconnected lsaps */
@@ -292,6 +288,9 @@ void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify)
        lap->saddr = saddr;
        lap->daddr = DEV_ADDR_ANY;
        lap->lsaps = hashbin_new(HB_GLOBAL);
+#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
+       lap->cache.valid = FALSE;
+#endif
 
        lap->lap_state = LAP_STANDBY;
        
@@ -602,7 +601,7 @@ struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance)
 
        /* Make sure that we invalidate the cache */
 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
-       irlmp->cache.valid = FALSE;
+       new->lap->cache.valid = FALSE;
 #endif /* CONFIG_IRDA_CACHE_LAST_LSAP */
 
        return new;
@@ -692,17 +691,16 @@ void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason,
                return;
        }
 
-#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
-       irlmp->cache.valid = FALSE;
-#endif
-
        /* 
         *  Remove association between this LSAP and the link it used 
         */
        ASSERT(self->lap != NULL, return;);
        ASSERT(self->lap->lsaps != NULL, return;);
-
+       
        lsap = hashbin_remove(self->lap->lsaps, (int) self, NULL);
+#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
+       self->lap->cache.valid = FALSE;
+#endif
 
        ASSERT(lsap != NULL, return;);
        ASSERT(lsap == self, return;);
index 3b1dd10ea1eb232bf6afa83fe2c8a75d23e74073..717038d89a1c16ded6ba9a11366eb4c9563a3bfd 100644 (file)
@@ -408,13 +408,14 @@ void irlmp_link_discovery_confirm(struct lap_cb *self, hashbin_t *log)
 }
 
 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
-inline void irlmp_update_cache(struct lsap_cb *self)
+static inline void irlmp_update_cache(struct lap_cb *lap,
+                                     struct lsap_cb *lsap)
 {
        /* Update cache entry */
-       irlmp->cache.dlsap_sel = self->dlsap_sel;
-       irlmp->cache.slsap_sel = self->slsap_sel;
-       irlmp->cache.lsap = self;
-       irlmp->cache.valid = TRUE;
+       lap->cache.dlsap_sel = lsap->dlsap_sel;
+       lap->cache.slsap_sel = lsap->slsap_sel;
+       lap->cache.lsap = lsap;
+       lap->cache.valid = TRUE;
 }
 #endif
 
@@ -423,6 +424,17 @@ inline void irlmp_update_cache(struct lsap_cb *self)
  *
  *    Find handle assosiated with destination and source LSAP
  *
+ * Any IrDA connection (LSAP/TSAP) is uniquely identified by
+ * 3 parameters, the local lsap, the remote lsap and the remote address. 
+ * We may initiate multiple connections to the same remote service
+ * (they will have different local lsap), a remote device may initiate
+ * multiple connections to the same local service (they will have
+ * different remote lsap), or multiple devices may connect to the same
+ * service and may use the same remote lsap (and they will have
+ * different remote address).
+ * So, where is the remote address ? Each LAP connection is made with
+ * a single remote device, so imply a specific remote address.
+ * Jean II
  */
 static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel,
                                       __u8 slsap_sel, int status,
@@ -436,11 +448,11 @@ static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel,
         *  cache first to avoid the linear search
         */
 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
-       if ((irlmp->cache.valid) && 
-           (irlmp->cache.slsap_sel == slsap_sel) && 
-           (irlmp->cache.dlsap_sel == dlsap_sel)) 
+       if ((self->cache.valid) && 
+           (self->cache.slsap_sel == slsap_sel) && 
+           (self->cache.dlsap_sel == dlsap_sel)) 
        {
-               return (irlmp->cache.lsap);
+               return (self->cache.lsap);
        }
 #endif
        lsap = (struct lsap_cb *) hashbin_get_first(queue);
@@ -458,7 +470,7 @@ static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel,
                        lsap->dlsap_sel = dlsap_sel;
                        
 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
-                       irlmp_update_cache(lsap);
+                       irlmp_update_cache(self, lsap);
 #endif
                        return lsap;
                }
@@ -469,7 +481,7 @@ static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel,
                    (lsap->dlsap_sel == dlsap_sel)) 
                {
 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
-                       irlmp_update_cache(lsap);
+                       irlmp_update_cache(self, lsap);
 #endif
                        return lsap;
                }