patch-2.4.21 linux-2.4.21/net/irda/irlmp.c
Next file: linux-2.4.21/net/irda/irlmp_event.c
Previous file: linux-2.4.21/net/irda/irlap_event.c
Back to the patch index
Back to the overall index
- Lines: 108
- Date:
2003-06-13 07:51:39.000000000 -0700
- Orig file:
linux-2.4.20/net/irda/irlmp.c
- Orig date:
2002-11-28 15:53:16.000000000 -0800
diff -urN linux-2.4.20/net/irda/irlmp.c linux-2.4.21/net/irda/irlmp.c
@@ -236,6 +236,16 @@
lap = self->lap;
if (lap) {
ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
+ /* We might close a LSAP before it has completed the
+ * connection setup. In those case, higher layers won't
+ * send a proper disconnect request. Harmless, except
+ * that we will forget to close LAP... - Jean II */
+ if(self->lsap_state != LSAP_DISCONNECTED) {
+ self->lsap_state = LSAP_DISCONNECTED;
+ irlmp_do_lap_event(self->lap,
+ LM_LAP_DISCONNECT_REQUEST, NULL);
+ }
+ /* Now, remove from the link */
lsap = hashbin_remove(lap->lsaps, (int) self, NULL);
}
self->lap = NULL;
@@ -1210,6 +1220,72 @@
}
/*
+ * Receive flow control indication from LAP.
+ * LAP want us to send it one more frame. We implement a simple round
+ * robin scheduler between the active sockets so that we get a bit of
+ * fairness. Note that the round robin is far from perfect, but it's
+ * better than nothing.
+ * We then poll the selected socket so that we can do synchronous
+ * refilling of IrLAP (which allow to minimise the number of buffers).
+ * Jean II
+ */
+void irlmp_flow_indication(struct lap_cb *self, LOCAL_FLOW flow)
+{
+ struct lsap_cb *next;
+ struct lsap_cb *curr;
+ int lsap_todo;
+
+ ASSERT(self->magic == LMP_LAP_MAGIC, return;);
+ ASSERT(flow == FLOW_START, return;);
+
+ /* Get the number of lsap. That's the only safe way to know
+ * that we have looped around... - Jean II */
+ lsap_todo = HASHBIN_GET_SIZE(self->lsaps);
+ IRDA_DEBUG(4, __FUNCTION__ "() : %d lsaps to scan\n", lsap_todo);
+
+ /* Poll lsap in order until the queue is full or until we
+ * tried them all.
+ * Most often, the current LSAP will have something to send,
+ * so we will go through this loop only once. - Jean II */
+ while((lsap_todo--) &&
+ (IRLAP_GET_TX_QUEUE_LEN(self->irlap) < LAP_HIGH_THRESHOLD)) {
+ /* Try to find the next lsap we should poll. */
+ next = self->flow_next;
+ if(next != NULL) {
+ /* Note that if there is only one LSAP on the LAP
+ * (most common case), self->flow_next is always NULL,
+ * so we always avoid this loop. - Jean II */
+ IRDA_DEBUG(4, __FUNCTION__ "() : searching my LSAP\n");
+
+ /* We look again in hashbins, because the lsap
+ * might have gone away... - Jean II */
+ curr = (struct lsap_cb *) hashbin_get_first(self->lsaps);
+ while((curr != NULL ) && (curr != next))
+ curr = (struct lsap_cb *) hashbin_get_next(self->lsaps);
+ } else
+ curr = NULL;
+
+ /* If we have no lsap, restart from first one */
+ if(curr == NULL)
+ curr = (struct lsap_cb *) hashbin_get_first(self->lsaps);
+ /* Uh-oh... Paranoia */
+ if(curr == NULL)
+ break;
+
+ /* Next time, we will get the next one (or the first one) */
+ self->flow_next = (struct lsap_cb *) hashbin_get_next(self->lsaps);
+ IRDA_DEBUG(4, __FUNCTION__ "() : curr is %p, next was %p and is now %p, still %d to go - queue len = %d\n", curr, next, self->flow_next, lsap_todo, IRLAP_GET_TX_QUEUE_LEN(self->irlap));
+
+ /* Inform lsap user that it can send one more packet. */
+ if (curr->notify.flow_indication != NULL)
+ curr->notify.flow_indication(curr->notify.instance,
+ curr, flow);
+ else
+ IRDA_DEBUG(1, __FUNCTION__ "(), no handler\n");
+ }
+}
+
+/*
* Function irlmp_hint_to_service (hint)
*
* Returns a list of all servics contained in the given hint bits. This
@@ -1674,7 +1750,7 @@
len += sprintf( buf+len, "Unconnected LSAPs:\n");
self = (struct lsap_cb *) hashbin_get_first( irlmp->unconnected_lsaps);
while (self != NULL) {
- ASSERT(self->magic == LMP_LSAP_MAGIC, return 0;);
+ ASSERT(self->magic == LMP_LSAP_MAGIC, break;);
len += sprintf(buf+len, "lsap state: %s, ",
irlsap_state[ self->lsap_state]);
len += sprintf(buf+len,
@@ -1703,7 +1779,7 @@
len += sprintf(buf+len, "\n Connected LSAPs:\n");
self = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
while (self != NULL) {
- ASSERT(self->magic == LMP_LSAP_MAGIC, return 0;);
+ ASSERT(self->magic == LMP_LSAP_MAGIC, break;);
len += sprintf(buf+len, " lsap state: %s, ",
irlsap_state[ self->lsap_state]);
len += sprintf(buf+len,
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)