diff -u -p linux/include/net/irda/irqueue.d1.h linux/include/net/irda/irqueue.h --- linux/include/net/irda/irqueue.d1.h Tue Jun 18 16:02:27 2002 +++ linux/include/net/irda/irqueue.h Tue Jun 18 15:58:08 2002 @@ -67,7 +67,7 @@ struct irda_queue { struct irda_queue *q_prev; char q_name[NAME_SIZE]; - __u32 q_hash; + int q_hash; }; typedef struct irda_queue irda_queue_t; @@ -84,10 +84,10 @@ typedef struct hashbin_t { hashbin_t *hashbin_new(int type); int hashbin_delete(hashbin_t* hashbin, FREE_FUNC 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, int hashv, char* name); -void* hashbin_find(hashbin_t* hashbin, __u32 hashv, char* name); -void* hashbin_remove(hashbin_t* hashbin, __u32 hashv, char* name); +void* hashbin_find(hashbin_t* hashbin, int hashv, char* name); +void* hashbin_remove(hashbin_t* hashbin, int hashv, char* name); void* hashbin_remove_first(hashbin_t *hashbin); void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry); irda_queue_t *hashbin_get_first(hashbin_t *hashbin); diff -u -p linux/include/net/irda/irlmp.d1.h linux/include/net/irda/irlmp.h --- linux/include/net/irda/irlmp.d1.h Tue Jun 18 15:44:28 2002 +++ linux/include/net/irda/irlmp.h Tue Jun 18 16:00:48 2002 @@ -197,12 +197,12 @@ struct lsap_cb *irlmp_open_lsap(__u8 sls void irlmp_close_lsap( struct lsap_cb *self); __u16 irlmp_service_to_hint(int service); -__u32 irlmp_register_service(__u16 hints); -int irlmp_unregister_service(__u32 handle); -__u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb, +void *irlmp_register_service(__u16 hints); +int irlmp_unregister_service(void *handle); +void *irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb, DISCOVERY_CALLBACK1 expir_clb, void *priv); -int irlmp_unregister_client(__u32 handle); -int irlmp_update_client(__u32 handle, __u16 hint_mask, +int irlmp_unregister_client(void *handle); +int irlmp_update_client(void *handle, __u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb, DISCOVERY_CALLBACK1 expir_clb, void *priv); diff -u -p linux/include/net/irda/af_irda.d1.h linux/include/net/irda/af_irda.h --- linux/include/net/irda/af_irda.d1.h Tue Jun 18 16:06:21 2002 +++ linux/include/net/irda/af_irda.h Tue Jun 18 16:06:47 2002 @@ -55,8 +55,8 @@ struct irda_sock { __u16 mask; /* Hint bits mask */ __u16 hints; /* Hint bits */ - __u32 ckey; /* IrLMP client handle */ - __u32 skey; /* IrLMP service handle */ + void *ckey; /* IrLMP client handle */ + void *skey; /* IrLMP service handle */ struct ias_object *ias_obj; /* Our service name + lsap in IAS */ struct iriap_cb *iriap; /* Used to query remote IAS */ diff -u -p linux/include/net/irda/ircomm_tty.d1.h linux/include/net/irda/ircomm_tty.h --- linux/include/net/irda/ircomm_tty.d1.h Tue Jun 18 16:09:54 2002 +++ linux/include/net/irda/ircomm_tty.h Tue Jun 18 16:10:59 2002 @@ -86,8 +86,8 @@ struct ircomm_tty_cb { struct iriap_cb *iriap; /* Instance used for querying remote IAS */ struct ias_object* obj; - int skey; - int ckey; + void *skey; + void *ckey; struct termios normal_termios; struct termios callout_termios; diff -u -p linux/net/irda/irqueue.d1.c linux/net/irda/irqueue.c --- linux/net/irda/irqueue.d1.c Tue Jun 18 15:21:53 2002 +++ linux/net/irda/irqueue.c Tue Jun 18 16:58:38 2002 @@ -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 #include @@ -148,7 +163,7 @@ int hashbin_delete( hashbin_t* 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, int hashv, char* name) { unsigned long flags = 0; int bin; @@ -209,7 +224,7 @@ void hashbin_insert(hashbin_t* hashbin, * Find item with the given hashv or name * */ -void* hashbin_find( hashbin_t* hashbin, __u32 hashv, char* name ) +void* hashbin_find( hashbin_t* hashbin, int hashv, char* name ) { int bin, found = FALSE; unsigned long flags = 0; @@ -300,8 +315,16 @@ void *hashbin_remove_first( hashbin_t *h * * 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, int hashv, char* name) { int bin, found = FALSE; unsigned long flags = 0; @@ -404,7 +427,7 @@ void* hashbin_remove_this( hashbin_t* ha { unsigned long flags = 0; int bin; - __u32 hashv; + int hashv; IRDA_DEBUG( 4, __FUNCTION__ "()\n"); diff -u -p linux/net/irda/irlmp.d1.c linux/net/irda/irlmp.c --- linux/net/irda/irlmp.d1.c Tue Jun 18 15:44:12 2002 +++ linux/net/irda/irlmp.c Tue Jun 18 16:35:33 2002 @@ -1414,20 +1414,12 @@ __u16 irlmp_service_to_hint(int service) * Register local service with IrLMP * */ -__u32 irlmp_register_service(__u16 hints) +void *irlmp_register_service(__u16 hints) { irlmp_service_t *service; - __u32 handle; 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 */ service = kmalloc(sizeof(irlmp_service_t), GFP_ATOMIC); if (!service) { @@ -1435,9 +1427,11 @@ __u32 irlmp_register_service(__u16 hints return 0; } service->hints = hints; - hashbin_insert(irlmp->services, (irda_queue_t *) service, handle, NULL); + hashbin_insert(irlmp->services, (irda_queue_t *) service, (int) service, NULL); - return handle; + irlmp->hints.word |= hints; + + return (void *)service; } /* @@ -1447,7 +1441,7 @@ __u32 irlmp_register_service(__u16 hints * * Returns: 0 on success, -1 on error */ -int irlmp_unregister_service(__u32 handle) +int irlmp_unregister_service(void *handle) { irlmp_service_t *service; @@ -1456,15 +1450,15 @@ int irlmp_unregister_service(__u32 handl if (!handle) 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, (int) handle, NULL); if (!service) { IRDA_DEBUG(1, __FUNCTION__ "(), Unknown service!\n"); return -1; } - service = hashbin_remove(irlmp->services, handle, NULL); - if (service) - kfree(service); + hashbin_remove_this(irlmp->services, (irda_queue_t *) service); + kfree(service); /* Remove old hint bits */ irlmp->hints.word = 0; @@ -1488,20 +1482,14 @@ int irlmp_unregister_service(__u32 handl * * 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) { irlmp_client_t *client; - __u32 handle; IRDA_DEBUG(1, __FUNCTION__ "()\n"); 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 */ client = kmalloc(sizeof(irlmp_client_t), GFP_ATOMIC); if (!client) { @@ -1515,9 +1503,9 @@ __u32 irlmp_register_client(__u16 hint_m client->expir_callback = expir_clb; client->priv = priv; - hashbin_insert(irlmp->clients, (irda_queue_t *) client, handle, NULL); + hashbin_insert(irlmp->clients, (irda_queue_t *) client, (int) client, NULL); - return handle; + return (void *) client; } /* @@ -1528,7 +1516,7 @@ __u32 irlmp_register_client(__u16 hint_m * * 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 expir_clb, void *priv) { @@ -1537,7 +1525,7 @@ int irlmp_update_client(__u32 handle, __ if (!handle) return -1; - client = hashbin_find(irlmp->clients, handle, NULL); + client = hashbin_find(irlmp->clients, (int) handle, NULL); if (!client) { IRDA_DEBUG(1, __FUNCTION__ "(), Unknown client!\n"); return -1; @@ -1557,7 +1545,7 @@ int irlmp_update_client(__u32 handle, __ * Returns: 0 on success, -1 on error * */ -int irlmp_unregister_client(__u32 handle) +int irlmp_unregister_client(void *handle) { struct irlmp_client *client; @@ -1566,16 +1554,16 @@ int irlmp_unregister_client(__u32 handle if (!handle) 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, (int) handle, NULL); if (!client) { IRDA_DEBUG(1, __FUNCTION__ "(), Unknown client!\n"); return -1; } IRDA_DEBUG( 4, __FUNCTION__ "(), removing client!\n"); - client = hashbin_remove( irlmp->clients, handle, NULL); - if (client) - kfree(client); + hashbin_remove_this(irlmp->clients, (irda_queue_t *) client); + kfree(client); return 0; } diff -u -p linux/net/irda/iriap.d1.c linux/net/irda/iriap.c --- linux/net/irda/iriap.d1.c Tue Jun 18 16:04:58 2002 +++ linux/net/irda/iriap.c Tue Jun 18 16:05:13 2002 @@ -58,7 +58,7 @@ static const char *ias_charset_types[] = #endif /* CONFIG_IRDA_DEBUG */ static hashbin_t *iriap = NULL; -static __u32 service_handle; +static void *service_handle; extern char *lmp_reasons[]; diff -u -p linux/net/irda/irias_object.d1.c linux/net/irda/irias_object.c --- linux/net/irda/irias_object.d1.c Tue Jun 18 15:19:21 2002 +++ linux/net/irda/irias_object.c Tue Jun 18 16:46:36 2002 @@ -147,7 +147,7 @@ int irias_delete_object(struct ias_objec ASSERT(obj != NULL, 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) return 0; /* Already removed */ @@ -172,7 +172,7 @@ int irias_delete_attrib(struct ias_objec ASSERT(attrib != NULL, return -1;); /* Remove attribute from object */ - node = hashbin_remove(obj->attribs, 0, attrib->name); + node = hashbin_remove_this(obj->attribs, (irda_queue_t *) attrib); if (!node) return 0; /* Already removed or non-existent */ diff -u -p linux/net/irda/irlan/irlan_common.d1.c linux/net/irda/irlan/irlan_common.c --- linux/net/irda/irlan/irlan_common.d1.c Tue Jun 18 16:12:19 2002 +++ linux/net/irda/irlan/irlan_common.c Tue Jun 18 16:12:43 2002 @@ -64,7 +64,8 @@ * Master structure */ hashbin_t *irlan = NULL; -static __u32 ckey, skey; +static void *ckey; +static void *skey; /* Module parameters */ static int eth = 0; /* Use "eth" or "irlan" name for devices */ diff -u -p linux/net/irda/irnet/irnet.d1.h linux/net/irda/irnet/irnet.h --- linux/net/irda/irnet/irnet.d1.h Tue Jun 18 16:13:34 2002 +++ linux/net/irda/irnet/irnet.h Tue Jun 18 16:14:46 2002 @@ -434,7 +434,7 @@ typedef struct irnet_socket /* ------------------- IrLMP and IrIAS part ------------------- */ /* Used for IrDA Discovery and socket name resolution */ - __u32 ckey; /* IrLMP client handle */ + void * ckey; /* IrLMP client handle */ __u16 mask; /* Hint bits mask (filter discov.)*/ int nslots; /* Number of slots for discovery */ diff -u -p linux/net/irda/irnet/irnet_irda.d1.h linux/net/irda/irnet/irnet_irda.h --- linux/net/irda/irnet/irnet_irda.d1.h Tue Jun 18 16:13:27 2002 +++ linux/net/irda/irnet/irnet_irda.h Tue Jun 18 16:15:25 2002 @@ -53,7 +53,7 @@ typedef struct irnet_root * reentrant, beware... So, we blindly protect all with spinlock */ /* Handle for the hint bit advertised in IrLMP */ - __u32 skey; + void * skey; /* Server socket part */ struct ias_object * ias_obj; /* Our service name + lsap in IAS */ diff -u -p linux/net/irda/irsyms.d1.c linux/net/irda/irsyms.c --- linux/net/irda/irsyms.d1.c Tue Jun 18 17:12:31 2002 +++ linux/net/irda/irsyms.c Tue Jun 18 17:15:33 2002 @@ -328,7 +328,8 @@ void __exit irda_cleanup(void) * On the other hand, it needs to be initialised *after* the basic * networking, the /proc/net filesystem and sysctl module. Those are * 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 */