Commit 57dd59ee authored by Jean Tourrilhes's avatar Jean Tourrilhes Committed by Jeff Garzik

irda update 1/6:

o [CRITICA] Remove correct IAS Attribute/Object even if name is dup'ed
o [CORRECT] Make irqueue 64 bit compliant (__u32 -> long)
o [FEATURE] Don't use random handle for IrLMP handle, use self
  Remove dependancy on random generator in stack init
parent 5f761bd3
...@@ -55,8 +55,8 @@ struct irda_sock { ...@@ -55,8 +55,8 @@ struct irda_sock {
__u16 mask; /* Hint bits mask */ __u16 mask; /* Hint bits mask */
__u16 hints; /* Hint bits */ __u16 hints; /* Hint bits */
__u32 ckey; /* IrLMP client handle */ void *ckey; /* IrLMP client handle */
__u32 skey; /* IrLMP service handle */ void *skey; /* IrLMP service handle */
struct ias_object *ias_obj; /* Our service name + lsap in IAS */ struct ias_object *ias_obj; /* Our service name + lsap in IAS */
struct iriap_cb *iriap; /* Used to query remote IAS */ struct iriap_cb *iriap; /* Used to query remote IAS */
......
...@@ -86,8 +86,8 @@ struct ircomm_tty_cb { ...@@ -86,8 +86,8 @@ struct ircomm_tty_cb {
struct iriap_cb *iriap; /* Instance used for querying remote IAS */ struct iriap_cb *iriap; /* Instance used for querying remote IAS */
struct ias_object* obj; struct ias_object* obj;
int skey; void *skey;
int ckey; void *ckey;
struct termios normal_termios; struct termios normal_termios;
struct termios callout_termios; struct termios callout_termios;
......
...@@ -197,12 +197,12 @@ struct lsap_cb *irlmp_open_lsap(__u8 slsap, notify_t *notify, __u8 pid); ...@@ -197,12 +197,12 @@ struct lsap_cb *irlmp_open_lsap(__u8 slsap, notify_t *notify, __u8 pid);
void irlmp_close_lsap( struct lsap_cb *self); void irlmp_close_lsap( struct lsap_cb *self);
__u16 irlmp_service_to_hint(int service); __u16 irlmp_service_to_hint(int service);
__u32 irlmp_register_service(__u16 hints); void *irlmp_register_service(__u16 hints);
int irlmp_unregister_service(__u32 handle); int irlmp_unregister_service(void *handle);
__u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb, void *irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb,
DISCOVERY_CALLBACK1 expir_clb, void *priv); DISCOVERY_CALLBACK1 expir_clb, void *priv);
int irlmp_unregister_client(__u32 handle); int irlmp_unregister_client(void *handle);
int irlmp_update_client(__u32 handle, __u16 hint_mask, int irlmp_update_client(void *handle, __u16 hint_mask,
DISCOVERY_CALLBACK1 disco_clb, DISCOVERY_CALLBACK1 disco_clb,
DISCOVERY_CALLBACK1 expir_clb, void *priv); DISCOVERY_CALLBACK1 expir_clb, void *priv);
......
...@@ -67,7 +67,7 @@ struct irda_queue { ...@@ -67,7 +67,7 @@ struct irda_queue {
struct irda_queue *q_prev; struct irda_queue *q_prev;
char q_name[NAME_SIZE]; char q_name[NAME_SIZE];
__u32 q_hash; long q_hash; /* Must be able to cast a (void *) */
}; };
typedef struct irda_queue irda_queue_t; typedef struct irda_queue irda_queue_t;
...@@ -84,10 +84,10 @@ typedef struct hashbin_t { ...@@ -84,10 +84,10 @@ typedef struct hashbin_t {
hashbin_t *hashbin_new(int type); hashbin_t *hashbin_new(int type);
int hashbin_delete(hashbin_t* hashbin, FREE_FUNC func); int hashbin_delete(hashbin_t* hashbin, FREE_FUNC func);
int hashbin_clear(hashbin_t* hashbin, FREE_FUNC free_func); int hashbin_clear(hashbin_t* hashbin, FREE_FUNC free_func);
void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, __u32 hashv, void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, long hashv,
char* name); char* name);
void* hashbin_find(hashbin_t* hashbin, __u32 hashv, char* name); void* hashbin_find(hashbin_t* hashbin, long hashv, char* name);
void* hashbin_remove(hashbin_t* hashbin, __u32 hashv, char* name); void* hashbin_remove(hashbin_t* hashbin, long hashv, char* name);
void* hashbin_remove_first(hashbin_t *hashbin); void* hashbin_remove_first(hashbin_t *hashbin);
void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry); void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry);
irda_queue_t *hashbin_get_first(hashbin_t *hashbin); irda_queue_t *hashbin_get_first(hashbin_t *hashbin);
......
...@@ -58,7 +58,7 @@ static const char *ias_charset_types[] = { ...@@ -58,7 +58,7 @@ static const char *ias_charset_types[] = {
#endif /* CONFIG_IRDA_DEBUG */ #endif /* CONFIG_IRDA_DEBUG */
static hashbin_t *iriap = NULL; static hashbin_t *iriap = NULL;
static __u32 service_handle; static void *service_handle;
extern char *lmp_reasons[]; extern char *lmp_reasons[];
...@@ -182,7 +182,7 @@ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv, ...@@ -182,7 +182,7 @@ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv,
init_timer(&self->watchdog_timer); init_timer(&self->watchdog_timer);
hashbin_insert(iriap, (irda_queue_t *) self, (int) self, NULL); hashbin_insert(iriap, (irda_queue_t *) self, (long) self, NULL);
/* Initialize state machines */ /* Initialize state machines */
iriap_next_client_state(self, S_DISCONNECT); iriap_next_client_state(self, S_DISCONNECT);
...@@ -235,7 +235,7 @@ void iriap_close(struct iriap_cb *self) ...@@ -235,7 +235,7 @@ void iriap_close(struct iriap_cb *self)
self->lsap = NULL; self->lsap = NULL;
} }
entry = (struct iriap_cb *) hashbin_remove(iriap, (int) self, NULL); entry = (struct iriap_cb *) hashbin_remove(iriap, (long) self, NULL);
ASSERT(entry == self, return;); ASSERT(entry == self, return;);
__iriap_close(self); __iriap_close(self);
......
...@@ -147,7 +147,7 @@ int irias_delete_object(struct ias_object *obj) ...@@ -147,7 +147,7 @@ int irias_delete_object(struct ias_object *obj)
ASSERT(obj != NULL, return -1;); ASSERT(obj != NULL, return -1;);
ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;); ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
node = hashbin_remove(objects, 0, obj->name); node = hashbin_remove_this(objects, (irda_queue_t *) obj);
if (!node) if (!node)
return 0; /* Already removed */ return 0; /* Already removed */
...@@ -172,7 +172,7 @@ int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib) ...@@ -172,7 +172,7 @@ int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib)
ASSERT(attrib != NULL, return -1;); ASSERT(attrib != NULL, return -1;);
/* Remove attribute from object */ /* Remove attribute from object */
node = hashbin_remove(obj->attribs, 0, attrib->name); node = hashbin_remove_this(obj->attribs, (irda_queue_t *) attrib);
if (!node) if (!node)
return 0; /* Already removed or non-existent */ return 0; /* Already removed or non-existent */
......
...@@ -177,8 +177,8 @@ struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, notify_t *notify, __u8 pid) ...@@ -177,8 +177,8 @@ struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, notify_t *notify, __u8 pid)
self->lsap_state = LSAP_DISCONNECTED; self->lsap_state = LSAP_DISCONNECTED;
/* Insert into queue of unconnected LSAPs */ /* Insert into queue of unconnected LSAPs */
hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self, (int) self, hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self,
NULL); (long) self, NULL);
return self; return self;
} }
...@@ -238,7 +238,7 @@ void irlmp_close_lsap(struct lsap_cb *self) ...@@ -238,7 +238,7 @@ void irlmp_close_lsap(struct lsap_cb *self)
LM_LAP_DISCONNECT_REQUEST, NULL); LM_LAP_DISCONNECT_REQUEST, NULL);
} }
/* Now, remove from the link */ /* Now, remove from the link */
lsap = hashbin_remove(lap->lsaps, (int) self, NULL); lsap = hashbin_remove(lap->lsaps, (long) self, NULL);
#ifdef CONFIG_IRDA_CACHE_LAST_LSAP #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
lap->cache.valid = FALSE; lap->cache.valid = FALSE;
#endif #endif
...@@ -246,7 +246,7 @@ void irlmp_close_lsap(struct lsap_cb *self) ...@@ -246,7 +246,7 @@ void irlmp_close_lsap(struct lsap_cb *self)
self->lap = NULL; self->lap = NULL;
/* Check if we found the LSAP! If not then try the unconnected lsaps */ /* Check if we found the LSAP! If not then try the unconnected lsaps */
if (!lsap) { if (!lsap) {
lsap = hashbin_remove(irlmp->unconnected_lsaps, (int) self, lsap = hashbin_remove(irlmp->unconnected_lsaps, (long) self,
NULL); NULL);
} }
if (!lsap) { if (!lsap) {
...@@ -436,14 +436,15 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel, ...@@ -436,14 +436,15 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
* Remove LSAP from list of unconnected LSAPs and insert it into the * Remove LSAP from list of unconnected LSAPs and insert it into the
* list of connected LSAPs for the particular link * list of connected LSAPs for the particular link
*/ */
lsap = hashbin_remove(irlmp->unconnected_lsaps, (int) self, NULL); lsap = hashbin_remove(irlmp->unconnected_lsaps, (long) self, NULL);
ASSERT(lsap != NULL, return -1;); ASSERT(lsap != NULL, return -1;);
ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;); ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;);
ASSERT(lsap->lap != NULL, return -1;); ASSERT(lsap->lap != NULL, return -1;);
ASSERT(lsap->lap->magic == LMP_LAP_MAGIC, return -1;); ASSERT(lsap->lap->magic == LMP_LAP_MAGIC, return -1;);
hashbin_insert(self->lap->lsaps, (irda_queue_t *) self, (int) self, NULL); hashbin_insert(self->lap->lsaps, (irda_queue_t *) self, (long) self,
NULL);
set_bit(0, &self->connected); /* TRUE */ set_bit(0, &self->connected); /* TRUE */
...@@ -578,7 +579,7 @@ struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance) ...@@ -578,7 +579,7 @@ struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance)
IRDA_DEBUG(1, __FUNCTION__ "()\n"); IRDA_DEBUG(1, __FUNCTION__ "()\n");
/* Only allowed to duplicate unconnected LSAP's */ /* Only allowed to duplicate unconnected LSAP's */
if (!hashbin_find(irlmp->unconnected_lsaps, (int) orig, NULL)) { if (!hashbin_find(irlmp->unconnected_lsaps, (long) orig, NULL)) {
IRDA_DEBUG(0, __FUNCTION__ "(), unable to find LSAP\n"); IRDA_DEBUG(0, __FUNCTION__ "(), unable to find LSAP\n");
return NULL; return NULL;
} }
...@@ -595,8 +596,8 @@ struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance) ...@@ -595,8 +596,8 @@ struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance)
init_timer(&new->watchdog_timer); init_timer(&new->watchdog_timer);
hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) new, (int) new, hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) new,
NULL); (long) new, NULL);
/* Make sure that we invalidate the cache */ /* Make sure that we invalidate the cache */
#ifdef CONFIG_IRDA_CACHE_LAST_LSAP #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
...@@ -646,7 +647,7 @@ int irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata) ...@@ -646,7 +647,7 @@ int irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata)
ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;); ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
ASSERT(self->lap->lsaps != NULL, return -1;); ASSERT(self->lap->lsaps != NULL, return -1;);
lsap = hashbin_remove(self->lap->lsaps, (int) self, NULL); lsap = hashbin_remove(self->lap->lsaps, (long) self, NULL);
#ifdef CONFIG_IRDA_CACHE_LAST_LSAP #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
self->lap->cache.valid = FALSE; self->lap->cache.valid = FALSE;
#endif #endif
...@@ -655,8 +656,8 @@ int irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata) ...@@ -655,8 +656,8 @@ int irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata)
ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;); ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;);
ASSERT(lsap == self, return -1;); ASSERT(lsap == self, return -1;);
hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self, (int) self, hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self,
NULL); (long) self, NULL);
/* Reset some values */ /* Reset some values */
self->dlsap_sel = LSAP_ANY; self->dlsap_sel = LSAP_ANY;
...@@ -699,15 +700,15 @@ void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason, ...@@ -699,15 +700,15 @@ void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason,
ASSERT(self->lap != NULL, return;); ASSERT(self->lap != NULL, return;);
ASSERT(self->lap->lsaps != NULL, return;); ASSERT(self->lap->lsaps != NULL, return;);
lsap = hashbin_remove(self->lap->lsaps, (int) self, NULL); lsap = hashbin_remove(self->lap->lsaps, (long) self, NULL);
#ifdef CONFIG_IRDA_CACHE_LAST_LSAP #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
self->lap->cache.valid = FALSE; self->lap->cache.valid = FALSE;
#endif #endif
ASSERT(lsap != NULL, return;); ASSERT(lsap != NULL, return;);
ASSERT(lsap == self, return;); ASSERT(lsap == self, return;);
hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) lsap, (int) lsap, hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) lsap,
NULL); (long) lsap, NULL);
self->dlsap_sel = LSAP_ANY; self->dlsap_sel = LSAP_ANY;
self->lap = NULL; self->lap = NULL;
...@@ -1414,20 +1415,12 @@ __u16 irlmp_service_to_hint(int service) ...@@ -1414,20 +1415,12 @@ __u16 irlmp_service_to_hint(int service)
* Register local service with IrLMP * Register local service with IrLMP
* *
*/ */
__u32 irlmp_register_service(__u16 hints) void *irlmp_register_service(__u16 hints)
{ {
irlmp_service_t *service; irlmp_service_t *service;
__u32 handle;
IRDA_DEBUG(4, __FUNCTION__ "(), hints = %04x\n", hints); IRDA_DEBUG(4, __FUNCTION__ "(), hints = %04x\n", hints);
/* Get a unique handle for this service */
get_random_bytes(&handle, sizeof(handle));
while (hashbin_find(irlmp->services, handle, NULL) || !handle)
get_random_bytes(&handle, sizeof(handle));
irlmp->hints.word |= hints;
/* Make a new registration */ /* Make a new registration */
service = kmalloc(sizeof(irlmp_service_t), GFP_ATOMIC); service = kmalloc(sizeof(irlmp_service_t), GFP_ATOMIC);
if (!service) { if (!service) {
...@@ -1435,9 +1428,12 @@ __u32 irlmp_register_service(__u16 hints) ...@@ -1435,9 +1428,12 @@ __u32 irlmp_register_service(__u16 hints)
return 0; return 0;
} }
service->hints = hints; service->hints = hints;
hashbin_insert(irlmp->services, (irda_queue_t *) service, handle, NULL); hashbin_insert(irlmp->services, (irda_queue_t *) service,
(long) service, NULL);
irlmp->hints.word |= hints;
return handle; return (void *)service;
} }
/* /*
...@@ -1447,7 +1443,7 @@ __u32 irlmp_register_service(__u16 hints) ...@@ -1447,7 +1443,7 @@ __u32 irlmp_register_service(__u16 hints)
* *
* Returns: 0 on success, -1 on error * Returns: 0 on success, -1 on error
*/ */
int irlmp_unregister_service(__u32 handle) int irlmp_unregister_service(void *handle)
{ {
irlmp_service_t *service; irlmp_service_t *service;
...@@ -1456,15 +1452,15 @@ int irlmp_unregister_service(__u32 handle) ...@@ -1456,15 +1452,15 @@ int irlmp_unregister_service(__u32 handle)
if (!handle) if (!handle)
return -1; return -1;
service = hashbin_find(irlmp->services, handle, NULL); /* Caller may call with invalid handle (it's legal) - Jean II */
service = hashbin_find(irlmp->services, (long) handle, NULL);
if (!service) { if (!service) {
IRDA_DEBUG(1, __FUNCTION__ "(), Unknown service!\n"); IRDA_DEBUG(1, __FUNCTION__ "(), Unknown service!\n");
return -1; return -1;
} }
service = hashbin_remove(irlmp->services, handle, NULL); hashbin_remove_this(irlmp->services, (irda_queue_t *) service);
if (service) kfree(service);
kfree(service);
/* Remove old hint bits */ /* Remove old hint bits */
irlmp->hints.word = 0; irlmp->hints.word = 0;
...@@ -1488,20 +1484,14 @@ int irlmp_unregister_service(__u32 handle) ...@@ -1488,20 +1484,14 @@ int irlmp_unregister_service(__u32 handle)
* *
* Returns: handle > 0 on success, 0 on error * Returns: handle > 0 on success, 0 on error
*/ */
__u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb, void *irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb,
DISCOVERY_CALLBACK1 expir_clb, void *priv) DISCOVERY_CALLBACK1 expir_clb, void *priv)
{ {
irlmp_client_t *client; irlmp_client_t *client;
__u32 handle;
IRDA_DEBUG(1, __FUNCTION__ "()\n"); IRDA_DEBUG(1, __FUNCTION__ "()\n");
ASSERT(irlmp != NULL, return 0;); ASSERT(irlmp != NULL, return 0;);
/* Get a unique handle for this client */
get_random_bytes(&handle, sizeof(handle));
while (hashbin_find(irlmp->clients, handle, NULL) || !handle)
get_random_bytes(&handle, sizeof(handle));
/* Make a new registration */ /* Make a new registration */
client = kmalloc(sizeof(irlmp_client_t), GFP_ATOMIC); client = kmalloc(sizeof(irlmp_client_t), GFP_ATOMIC);
if (!client) { if (!client) {
...@@ -1515,9 +1505,10 @@ __u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb, ...@@ -1515,9 +1505,10 @@ __u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb,
client->expir_callback = expir_clb; client->expir_callback = expir_clb;
client->priv = priv; client->priv = priv;
hashbin_insert(irlmp->clients, (irda_queue_t *) client, handle, NULL); hashbin_insert(irlmp->clients, (irda_queue_t *) client,
(long) client, NULL);
return handle; return (void *) client;
} }
/* /*
...@@ -1528,7 +1519,7 @@ __u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb, ...@@ -1528,7 +1519,7 @@ __u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb,
* *
* Returns: 0 on success, -1 on error * Returns: 0 on success, -1 on error
*/ */
int irlmp_update_client(__u32 handle, __u16 hint_mask, int irlmp_update_client(void *handle, __u16 hint_mask,
DISCOVERY_CALLBACK1 disco_clb, DISCOVERY_CALLBACK1 disco_clb,
DISCOVERY_CALLBACK1 expir_clb, void *priv) DISCOVERY_CALLBACK1 expir_clb, void *priv)
{ {
...@@ -1537,7 +1528,7 @@ int irlmp_update_client(__u32 handle, __u16 hint_mask, ...@@ -1537,7 +1528,7 @@ int irlmp_update_client(__u32 handle, __u16 hint_mask,
if (!handle) if (!handle)
return -1; return -1;
client = hashbin_find(irlmp->clients, handle, NULL); client = hashbin_find(irlmp->clients, (long) handle, NULL);
if (!client) { if (!client) {
IRDA_DEBUG(1, __FUNCTION__ "(), Unknown client!\n"); IRDA_DEBUG(1, __FUNCTION__ "(), Unknown client!\n");
return -1; return -1;
...@@ -1557,7 +1548,7 @@ int irlmp_update_client(__u32 handle, __u16 hint_mask, ...@@ -1557,7 +1548,7 @@ int irlmp_update_client(__u32 handle, __u16 hint_mask,
* Returns: 0 on success, -1 on error * Returns: 0 on success, -1 on error
* *
*/ */
int irlmp_unregister_client(__u32 handle) int irlmp_unregister_client(void *handle)
{ {
struct irlmp_client *client; struct irlmp_client *client;
...@@ -1566,16 +1557,16 @@ int irlmp_unregister_client(__u32 handle) ...@@ -1566,16 +1557,16 @@ int irlmp_unregister_client(__u32 handle)
if (!handle) if (!handle)
return -1; return -1;
client = hashbin_find(irlmp->clients, handle, NULL); /* Caller may call with invalid handle (it's legal) - Jean II */
client = hashbin_find(irlmp->clients, (long) handle, NULL);
if (!client) { if (!client) {
IRDA_DEBUG(1, __FUNCTION__ "(), Unknown client!\n"); IRDA_DEBUG(1, __FUNCTION__ "(), Unknown client!\n");
return -1; return -1;
} }
IRDA_DEBUG( 4, __FUNCTION__ "(), removing client!\n"); IRDA_DEBUG( 4, __FUNCTION__ "(), removing client!\n");
client = hashbin_remove( irlmp->clients, handle, NULL); hashbin_remove_this(irlmp->clients, (irda_queue_t *) client);
if (client) kfree(client);
kfree(client);
return 0; return 0;
} }
......
...@@ -581,15 +581,15 @@ static int irlmp_state_connect(struct lsap_cb *self, IRLMP_EVENT event, ...@@ -581,15 +581,15 @@ static int irlmp_state_connect(struct lsap_cb *self, IRLMP_EVENT event,
* Bind this LSAP to the IrLAP link where the connect was * Bind this LSAP to the IrLAP link where the connect was
* received * received
*/ */
lsap = hashbin_remove(irlmp->unconnected_lsaps, (int) self, lsap = hashbin_remove(irlmp->unconnected_lsaps, (long) self,
NULL); NULL);
ASSERT(lsap == self, return -1;); ASSERT(lsap == self, return -1;);
ASSERT(self->lap != NULL, return -1;); ASSERT(self->lap != NULL, return -1;);
ASSERT(self->lap->lsaps != NULL, return -1;); ASSERT(self->lap->lsaps != NULL, return -1;);
hashbin_insert(self->lap->lsaps, (irda_queue_t *) self, (int) self, hashbin_insert(self->lap->lsaps, (irda_queue_t *) self,
NULL); (long) self, NULL);
irlmp_send_lcf_pdu(self->lap, self->dlsap_sel, irlmp_send_lcf_pdu(self->lap, self->dlsap_sel,
self->slsap_sel, CONNECT_CNF, skb); self->slsap_sel, CONNECT_CNF, skb);
......
...@@ -34,6 +34,21 @@ ...@@ -34,6 +34,21 @@
* *
********************************************************************/ ********************************************************************/
/*
* NOTE :
* There are various problems with this package :
* o the hash function for ints is pathetic (but could be changed)
* o locking is sometime suspicious (especially during enumeration)
* o most users have only a few elements (== overhead)
* o most users never use seach, so don't benefit from hashing
* Problem already fixed :
* o not 64 bit compliant (most users do hashv = (int) self)
* o hashbin_remove() is broken => use hashbin_remove_this()
* I think most users would be better served by a simple linked list
* (like include/linux/list.h) with a global spinlock per list.
* Jean II
*/
#include <net/irda/irda.h> #include <net/irda/irda.h>
#include <net/irda/irqueue.h> #include <net/irda/irqueue.h>
...@@ -148,7 +163,7 @@ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func) ...@@ -148,7 +163,7 @@ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func)
* Insert an entry into the hashbin * Insert an entry into the hashbin
* *
*/ */
void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, __u32 hashv, char* name) void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, long hashv, char* name)
{ {
unsigned long flags = 0; unsigned long flags = 0;
int bin; int bin;
...@@ -209,7 +224,7 @@ void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, __u32 hashv, char* ...@@ -209,7 +224,7 @@ void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, __u32 hashv, char*
* Find item with the given hashv or name * Find item with the given hashv or name
* *
*/ */
void* hashbin_find( hashbin_t* hashbin, __u32 hashv, char* name ) void* hashbin_find( hashbin_t* hashbin, long hashv, char* name )
{ {
int bin, found = FALSE; int bin, found = FALSE;
unsigned long flags = 0; unsigned long flags = 0;
...@@ -300,8 +315,16 @@ void *hashbin_remove_first( hashbin_t *hashbin) ...@@ -300,8 +315,16 @@ void *hashbin_remove_first( hashbin_t *hashbin)
* *
* Remove entry with the given name * Remove entry with the given name
* *
* The use of this function is highly discouraged, because the whole
* concept behind hashbin_remove() is broken. In many cases, it's not
* possible to guarantee the unicity of the index (either hashv or name),
* leading to removing the WRONG entry.
* The only simple safe use is :
* hashbin_remove(hasbin, (int) self, NULL);
* In other case, you must think hard to guarantee unicity of the index.
* Jean II
*/ */
void* hashbin_remove( hashbin_t* hashbin, __u32 hashv, char* name) void* hashbin_remove( hashbin_t* hashbin, long hashv, char* name)
{ {
int bin, found = FALSE; int bin, found = FALSE;
unsigned long flags = 0; unsigned long flags = 0;
...@@ -404,7 +427,7 @@ void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry) ...@@ -404,7 +427,7 @@ void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry)
{ {
unsigned long flags = 0; unsigned long flags = 0;
int bin; int bin;
__u32 hashv; long hashv;
IRDA_DEBUG( 4, __FUNCTION__ "()\n"); IRDA_DEBUG( 4, __FUNCTION__ "()\n");
......
...@@ -328,7 +328,8 @@ void __exit irda_cleanup(void) ...@@ -328,7 +328,8 @@ void __exit irda_cleanup(void)
* On the other hand, it needs to be initialised *after* the basic * On the other hand, it needs to be initialised *after* the basic
* networking, the /proc/net filesystem and sysctl module. Those are * networking, the /proc/net filesystem and sysctl module. Those are
* currently initialised in .../init/main.c (before initcalls). * currently initialised in .../init/main.c (before initcalls).
* Also, it needs to be initialised *after* the random number generator. * Also, IrDA drivers needs to be initialised *after* the random number
* generator (main stack and higher layer init don't need it anymore).
* *
* Jean II * Jean II
*/ */
......
...@@ -433,7 +433,7 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify) ...@@ -433,7 +433,7 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
self->notify = *notify; self->notify = *notify;
self->lsap = lsap; self->lsap = lsap;
hashbin_insert(irttp->tsaps, (irda_queue_t *) self, (int) self, NULL); hashbin_insert(irttp->tsaps, (irda_queue_t *) self, (long) self, NULL);
if (credit > TTP_RX_MAX_CREDIT) if (credit > TTP_RX_MAX_CREDIT)
self->initial_credit = TTP_RX_MAX_CREDIT; self->initial_credit = TTP_RX_MAX_CREDIT;
...@@ -503,7 +503,7 @@ int irttp_close_tsap(struct tsap_cb *self) ...@@ -503,7 +503,7 @@ int irttp_close_tsap(struct tsap_cb *self)
return 0; /* Will be back! */ return 0; /* Will be back! */
} }
tsap = hashbin_remove(irttp->tsaps, (int) self, NULL); tsap = hashbin_remove(irttp->tsaps, (long) self, NULL);
ASSERT(tsap == self, return -1;); ASSERT(tsap == self, return -1;);
...@@ -1368,7 +1368,7 @@ struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance) ...@@ -1368,7 +1368,7 @@ struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance)
IRDA_DEBUG(1, __FUNCTION__ "()\n"); IRDA_DEBUG(1, __FUNCTION__ "()\n");
if (!hashbin_find(irttp->tsaps, (int) orig, NULL)) { if (!hashbin_find(irttp->tsaps, (long) orig, NULL)) {
IRDA_DEBUG(0, __FUNCTION__ "(), unable to find TSAP\n"); IRDA_DEBUG(0, __FUNCTION__ "(), unable to find TSAP\n");
return NULL; return NULL;
} }
...@@ -1389,7 +1389,7 @@ struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance) ...@@ -1389,7 +1389,7 @@ struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance)
skb_queue_head_init(&new->tx_queue); skb_queue_head_init(&new->tx_queue);
skb_queue_head_init(&new->rx_fragments); skb_queue_head_init(&new->rx_fragments);
hashbin_insert(irttp->tsaps, (irda_queue_t *) new, (int) new, NULL); hashbin_insert(irttp->tsaps, (irda_queue_t *) new, (long) new, NULL);
return new; return new;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment