spin_lock_init(&irlmp->cachelog->hb_spinlock);
- irlmp->last_lsap_sel = 0x0f; /* Reserved 0x00-0x0f */
+ irlmp->free_lsap_sel = 0x10; /* Reserved 0x00-0x0f */
strcpy(sysctl_devname, "Linux");
/* Do discovery every 3 seconds */
/* Allocate new instance of a LSAP connection */
self = kmalloc(sizeof(struct lsap_cb), GFP_ATOMIC);
if (self == NULL) {
- ERROR("%s: can't allocate memory\n", __FUNCTION__);
+ ERROR("%s: can't allocate memory", __FUNCTION__);
return NULL;
}
memset(self, 0, sizeof(struct lsap_cb));
* Function irlmp_slsap_inuse (slsap)
*
* Check if the given source LSAP selector is in use
- *
- * This function is clearly not very efficient. On the mitigating side, the
- * stack make sure that in 99% of the cases, we are called only once
- * for each socket allocation. We could probably keep a bitmap
- * of the allocated LSAP, but I'm not sure the complexity is worth it.
- * Jean II
*/
int irlmp_slsap_inuse(__u8 slsap_sel)
{
return FALSE;
#endif /* CONFIG_IRDA_ULTRA */
- /* Valid values are between 0 and 127 (0x0-0x6F) */
+ /* Valid values are between 0 and 127 */
if (slsap_sel > LSAP_MAX)
return TRUE;
spin_lock_irqsave(&irlmp->links->hb_spinlock, flags);
lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
while (lap != NULL) {
- ASSERT(lap->magic == LMP_LAP_MAGIC, goto errlap;);
+ ASSERT(lap->magic == LMP_LAP_MAGIC, return TRUE;);
/* Careful for priority inversions here !
- * irlmp->links is never taken while another IrDA
- * spinlock is held, so we are safe. Jean II */
+ * All other uses of attrib spinlock are independent of
+ * the object spinlock, so we are safe. Jean II */
spin_lock(&lap->lsaps->hb_spinlock);
- /* For this IrLAP, check all the LSAPs */
self = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
while (self != NULL) {
- ASSERT(self->magic == LMP_LSAP_MAGIC, goto errlsap;);
+ ASSERT(self->magic == LMP_LSAP_MAGIC, return TRUE;);
if ((self->slsap_sel == slsap_sel)) {
IRDA_DEBUG(4, "Source LSAP selector=%02x in use\n",
- self->slsap_sel);
- goto errlsap;
+ self->slsap_sel);
+ return TRUE;
}
self = (struct lsap_cb*) hashbin_get_next(lap->lsaps);
}
spin_unlock(&lap->lsaps->hb_spinlock);
-
/* Next LAP */
lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
}
spin_unlock_irqrestore(&irlmp->links->hb_spinlock, flags);
-
- /*
- * Server sockets are typically waiting for connections and
- * therefore reside in the unconnected list. We don't want
- * to give out their LSAPs for obvious reasons...
- * Jean II
- */
- spin_lock_irqsave(&irlmp->unconnected_lsaps->hb_spinlock, flags);
-
- self = (struct lsap_cb *) hashbin_get_first(irlmp->unconnected_lsaps);
- while (self != NULL) {
- ASSERT(self->magic == LMP_LSAP_MAGIC, goto erruncon;);
- if ((self->slsap_sel == slsap_sel)) {
- IRDA_DEBUG(4, "Source LSAP selector=%02x in use (unconnected)\n",
- self->slsap_sel);
- goto erruncon;
- }
- self = (struct lsap_cb*) hashbin_get_next(irlmp->unconnected_lsaps);
- }
- spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, flags);
-
return FALSE;
-
- /* Error exit from within one of the two nested loops.
- * Make sure we release the right spinlock in the righ order.
- * Jean II */
-errlsap:
- spin_unlock(&lap->lsaps->hb_spinlock);
-errlap:
- spin_unlock_irqrestore(&irlmp->links->hb_spinlock, flags);
- return TRUE;
-
- /* Error exit from within the unconnected loop.
- * Just one spinlock to release... Jean II */
-erruncon:
- spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, flags);
- return TRUE;
}
/*
ASSERT(irlmp != NULL, return -1;);
ASSERT(irlmp->magic == LMP_MAGIC, return -1;);
- /* Most users don't really care which LSAPs they are given,
- * and therefore we automatically give them a free LSAP.
- * This function try to find a suitable LSAP, i.e. which is
- * not in use and is within the acceptable range. Jean II */
-
- do {
- /* Always increment to LSAP number before using it.
- * In theory, we could reuse the last LSAP number, as long
- * as it is no longer in use. Some IrDA stack do that.
- * However, the previous socket may be half closed, i.e.
- * we closed it, we think it's no longer in use, but the
- * other side did not receive our close and think it's
- * active and still send data on it.
- * This is similar to what is done with PIDs and TCP ports.
- * Also, this reduce the number of calls to irlmp_slsap_inuse()
- * which is an expensive function to call.
- * Jean II */
- irlmp->last_lsap_sel++;
+ lsap_sel = irlmp->free_lsap_sel++;
+
+ /* Check if the new free lsap is really free */
+ while (irlmp_slsap_inuse(irlmp->free_lsap_sel)) {
+ irlmp->free_lsap_sel++;
/* Check if we need to wraparound (0x70-0x7f are reserved) */
- if (irlmp->last_lsap_sel > LSAP_MAX) {
- /* 0x00-0x10 are also reserved for well know ports */
- irlmp->last_lsap_sel = 0x10;
+ if (irlmp->free_lsap_sel > LSAP_MAX) {
+ irlmp->free_lsap_sel = 10;
/* Make sure we terminate the loop */
- if (wrapped++) {
- ERROR("%s: no more free LSAPs !\n",
- __FUNCTION__);
+ if (wrapped++)
return 0;
- }
}
-
- /* If the LSAP is in use, try the next one.
- * Despite the autoincrement, we need to check if the lsap
- * is really in use or not, first because LSAP may be
- * directly allocated in irlmp_open_lsap(), and also because
- * we may wraparound on old sockets. Jean II */
- } while (irlmp_slsap_inuse(irlmp->last_lsap_sel));
-
- /* Got it ! */
- lsap_sel = irlmp->last_lsap_sel;
- IRDA_DEBUG(4, "%s(), found free lsap_sel=%02x\n",
+ }
+ IRDA_DEBUG(4, "%s(), next free lsap_sel=%02x\n",
__FUNCTION__, lsap_sel);
return lsap_sel;