bsc_rll: Stop using lchan refcounts, use the lchan signal to stop the timer

Stop using the lchan refcounts and start handling the lchan
release to stop timers and free the RLL resources for the
channel.
diff --git a/openbsc/src/bsc_rll.c b/openbsc/src/bsc_rll.c
index 9a4f5aa..a8e642f 100644
--- a/openbsc/src/bsc_rll.c
+++ b/openbsc/src/bsc_rll.c
@@ -31,6 +31,7 @@
 #include <openbsc/gsm_data.h>
 #include <openbsc/chan_alloc.h>
 #include <openbsc/abis_rsl.h>
+#include <openbsc/signal.h>
 
 struct bsc_rll_req {
 	struct llist_head list;
@@ -55,7 +56,6 @@
 
 	conn = &rllr->lchan->conn;
 	llist_del(&rllr->list);
-	put_subscr_con(conn);
 	rllr->cb(rllr->lchan, rllr->link_id, rllr->data, type);
 	talloc_free(rllr);
 }
@@ -88,7 +88,6 @@
 		link_id |= 0x40;
 
 	conn = &lchan->conn;
-	use_subscr_con(conn);
 	rllr->lchan = lchan;
 	rllr->link_id = link_id;
 	rllr->cb = cb;
@@ -120,3 +119,29 @@
 		}
 	}
 }
+
+static int rll_lchan_signal(unsigned int subsys, unsigned int signal,
+			    void *handler_data, void *signal_data)
+{
+	struct challoc_signal_data *challoc;
+	struct bsc_rll_req *rllr, *rllr2;
+
+	if (subsys != SS_CHALLOC || signal != S_CHALLOC_FREED)
+		return 0;
+
+	challoc = (struct challoc_signal_data *) signal_data;
+
+	llist_for_each_entry_safe(rllr, rllr2, &bsc_rll_reqs, list) {
+		if (rllr->lchan == challoc->lchan) {
+			bsc_del_timer(&rllr->timer);
+			complete_rllr(rllr, BSC_RLLR_IND_ERR_IND);
+		}
+	}
+
+	return 0;
+}
+
+static __attribute__((constructor)) void on_dso_load_rll(void)
+{
+	register_signal_handler(SS_CHALLOC, rll_lchan_signal, NULL);
+}