00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <net/irda/irda.h>
00036 #include <net/irda/irqueue.h>
00037 #include <net/irda/irmod.h>
00038
00039 static queue_t *dequeue_general( queue_t **queue, queue_t* element);
00040 static __u32 hash( char* name);
00041
00042
00043
00044
00045
00046
00047
00048 hashbin_t *hashbin_new(int type)
00049 {
00050 hashbin_t* hashbin;
00051 int i;
00052
00053
00054
00055
00056 hashbin = kmalloc( sizeof(hashbin_t), GFP_ATOMIC);
00057 if (!hashbin)
00058 return NULL;
00059
00060
00061
00062
00063 memset(hashbin, 0, sizeof(hashbin_t));
00064 hashbin->hb_type = type;
00065 hashbin->magic = HB_MAGIC;
00066
00067
00068 for (i=0;i<HASHBIN_SIZE;i++)
00069 hashbin->hb_mutex[i] = SPIN_LOCK_UNLOCKED;
00070
00071 return hashbin;
00072 }
00073
00074
00075
00076
00077
00078
00079
00080 int hashbin_clear( hashbin_t* hashbin, FREE_FUNC free_func)
00081 {
00082 queue_t* queue;
00083 int i;
00084
00085 ASSERT(hashbin != NULL, return -1;);
00086 ASSERT(hashbin->magic == HB_MAGIC, return -1;);
00087
00088
00089
00090
00091 for (i = 0; i < HASHBIN_SIZE; i ++ ) {
00092 queue = dequeue_first( (queue_t**) &hashbin->hb_queue[i]);
00093 while (queue) {
00094 if (free_func)
00095 (*free_func)(queue);
00096 queue = dequeue_first(
00097 (queue_t**) &hashbin->hb_queue[i]);
00098 }
00099 }
00100 hashbin->hb_size = 0;
00101
00102 return 0;
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func)
00114 {
00115 queue_t* queue;
00116 int i;
00117
00118 ASSERT(hashbin != NULL, return -1;);
00119 ASSERT(hashbin->magic == HB_MAGIC, return -1;);
00120
00121
00122
00123
00124
00125 for (i = 0; i < HASHBIN_SIZE; i ++ ) {
00126 queue = dequeue_first((queue_t**) &hashbin->hb_queue[i]);
00127 while (queue ) {
00128 if (free_func)
00129 (*free_func)(queue);
00130 queue = dequeue_first(
00131 (queue_t**) &hashbin->hb_queue[i]);
00132 }
00133 }
00134
00135
00136
00137
00138 hashbin->magic = ~HB_MAGIC;
00139 kfree(hashbin);
00140
00141 return 0;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150 void hashbin_lock(hashbin_t* hashbin, __u32 hashv, char* name,
00151 unsigned long flags)
00152 {
00153 int bin;
00154
00155 IRDA_DEBUG(0, "hashbin_lock\n");
00156
00157 ASSERT(hashbin != NULL, return;);
00158 ASSERT(hashbin->magic == HB_MAGIC, return;);
00159
00160
00161
00162
00163 if (name)
00164 hashv = hash(name);
00165 bin = GET_HASHBIN(hashv);
00166
00167
00168 if ( hashbin->hb_type & HB_GLOBAL )
00169 spin_lock_irqsave(&hashbin->hb_mutex[ bin], flags);
00170 else {
00171 save_flags(flags);
00172 cli();
00173 }
00174 }
00175
00176
00177
00178
00179
00180
00181
00182 void hashbin_unlock(hashbin_t* hashbin, __u32 hashv, char* name,
00183 unsigned long flags)
00184 {
00185 int bin;
00186
00187 IRDA_DEBUG(0, "hashbin_unlock()\n");
00188
00189 ASSERT(hashbin != NULL, return;);
00190 ASSERT(hashbin->magic == HB_MAGIC, return;);
00191
00192
00193
00194
00195 if (name )
00196 hashv = hash(name);
00197 bin = GET_HASHBIN(hashv);
00198
00199
00200 if ( hashbin->hb_type & HB_GLOBAL)
00201 spin_unlock_irq( &hashbin->hb_mutex[ bin]);
00202 else if (hashbin->hb_type & HB_LOCAL) {
00203 restore_flags( flags);
00204 }
00205 }
00206
00207
00208
00209
00210
00211
00212
00213 void hashbin_insert(hashbin_t* hashbin, queue_t* entry, __u32 hashv, char* name)
00214 {
00215 unsigned long flags = 0;
00216 int bin;
00217
00218 IRDA_DEBUG( 4, __FUNCTION__"()\n");
00219
00220 ASSERT( hashbin != NULL, return;);
00221 ASSERT( hashbin->magic == HB_MAGIC, return;);
00222
00223
00224
00225
00226 if ( name )
00227 hashv = hash( name );
00228 bin = GET_HASHBIN( hashv );
00229
00230
00231 if ( hashbin->hb_type & HB_GLOBAL ) {
00232 spin_lock_irqsave( &hashbin->hb_mutex[ bin ], flags);
00233
00234 } else if ( hashbin->hb_type & HB_LOCAL ) {
00235 save_flags(flags);
00236 cli();
00237 }
00238
00239
00240
00241
00242 entry->q_hash = hashv;
00243 if ( name )
00244 strncpy( entry->q_name, name, 32);
00245
00246
00247
00248
00249
00250
00251 if ( hashbin->hb_type & HB_SORTED) {
00252 } else {
00253 enqueue_first( (queue_t**) &hashbin->hb_queue[ bin ],
00254 entry);
00255 }
00256 hashbin->hb_size++;
00257
00258
00259 if ( hashbin->hb_type & HB_GLOBAL) {
00260
00261 spin_unlock_irq( &hashbin->hb_mutex[ bin]);
00262
00263 } else if ( hashbin->hb_type & HB_LOCAL) {
00264 restore_flags( flags);
00265 }
00266 }
00267
00268
00269
00270
00271
00272
00273
00274 void* hashbin_find( hashbin_t* hashbin, __u32 hashv, char* name )
00275 {
00276 int bin, found = FALSE;
00277 unsigned long flags = 0;
00278 queue_t* entry;
00279
00280 IRDA_DEBUG( 4, "hashbin_find()\n");
00281
00282 ASSERT( hashbin != NULL, return NULL;);
00283 ASSERT( hashbin->magic == HB_MAGIC, return NULL;);
00284
00285
00286
00287
00288 if ( name )
00289 hashv = hash( name );
00290 bin = GET_HASHBIN( hashv );
00291
00292
00293 if ( hashbin->hb_type & HB_GLOBAL ) {
00294 spin_lock_irqsave( &hashbin->hb_mutex[ bin ], flags);
00295
00296 } else if ( hashbin->hb_type & HB_LOCAL ) {
00297 save_flags(flags);
00298 cli();
00299 }
00300
00301
00302
00303
00304 entry = hashbin->hb_queue[ bin];
00305 if ( entry ) {
00306 do {
00307
00308
00309
00310 if ( entry->q_hash == hashv ) {
00311
00312
00313
00314 if ( name ) {
00315 if ( strcmp( entry->q_name, name ) == 0 ) {
00316 found = TRUE;
00317 break;
00318 }
00319 } else {
00320 found = TRUE;
00321 break;
00322 }
00323 }
00324 entry = entry->q_next;
00325 } while ( entry != hashbin->hb_queue[ bin ] );
00326 }
00327
00328
00329 if ( hashbin->hb_type & HB_GLOBAL) {
00330 spin_unlock_irq( &hashbin->hb_mutex[ bin]);
00331
00332 } else if ( hashbin->hb_type & HB_LOCAL) {
00333 restore_flags( flags);
00334 }
00335
00336 if ( found )
00337 return entry;
00338 else
00339 return NULL;
00340 }
00341
00342 void *hashbin_remove_first( hashbin_t *hashbin)
00343 {
00344 unsigned long flags;
00345 queue_t *entry = NULL;
00346
00347 save_flags(flags);
00348 cli();
00349
00350 entry = hashbin_get_first( hashbin);
00351 if ( entry != NULL)
00352 hashbin_remove( hashbin, entry->q_hash, NULL);
00353
00354 restore_flags( flags);
00355
00356 return entry;
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366 void* hashbin_remove( hashbin_t* hashbin, __u32 hashv, char* name)
00367 {
00368 int bin, found = FALSE;
00369 unsigned long flags = 0;
00370 queue_t* entry;
00371
00372 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
00373
00374 ASSERT( hashbin != NULL, return NULL;);
00375 ASSERT( hashbin->magic == HB_MAGIC, return NULL;);
00376
00377
00378
00379
00380 if ( name )
00381 hashv = hash( name );
00382 bin = GET_HASHBIN( hashv );
00383
00384 if ( hashbin->hb_type & HB_GLOBAL ) {
00385 spin_lock_irqsave( &hashbin->hb_mutex[ bin ], flags);
00386
00387 } else if ( hashbin->hb_type & HB_LOCAL ) {
00388 save_flags(flags);
00389 cli();
00390 }
00391
00392
00393
00394
00395 entry = hashbin->hb_queue[ bin ];
00396 if ( entry ) {
00397 do {
00398
00399
00400
00401 if ( entry->q_hash == hashv ) {
00402
00403
00404
00405 if ( name ) {
00406 if ( strcmp( entry->q_name, name) == 0)
00407 {
00408 found = TRUE;
00409 break;
00410 }
00411 } else {
00412 found = TRUE;
00413 break;
00414 }
00415 }
00416 entry = entry->q_next;
00417 } while ( entry != hashbin->hb_queue[ bin ] );
00418 }
00419
00420
00421
00422
00423 if ( found ) {
00424 dequeue_general( (queue_t**) &hashbin->hb_queue[ bin ],
00425 (queue_t*) entry );
00426 hashbin->hb_size--;
00427
00428
00429
00430
00431
00432 if ( entry == hashbin->hb_current)
00433 hashbin->hb_current = NULL;
00434 }
00435
00436
00437 if ( hashbin->hb_type & HB_GLOBAL) {
00438 spin_unlock_irq( &hashbin->hb_mutex[ bin]);
00439
00440 } else if ( hashbin->hb_type & HB_LOCAL) {
00441 restore_flags( flags);
00442 }
00443
00444
00445
00446 if ( found )
00447 return entry;
00448 else
00449 return NULL;
00450
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460 queue_t *hashbin_get_first( hashbin_t* hashbin)
00461 {
00462 queue_t *entry;
00463 int i;
00464
00465 ASSERT( hashbin != NULL, return NULL;);
00466 ASSERT( hashbin->magic == HB_MAGIC, return NULL;);
00467
00468 if ( hashbin == NULL)
00469 return NULL;
00470
00471 for ( i = 0; i < HASHBIN_SIZE; i ++ ) {
00472 entry = hashbin->hb_queue[ i];
00473 if ( entry) {
00474 hashbin->hb_current = entry;
00475 return entry;
00476 }
00477 }
00478
00479
00480
00481 return NULL;
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 queue_t *hashbin_get_next( hashbin_t *hashbin)
00493 {
00494 queue_t* entry;
00495 int bin;
00496 int i;
00497
00498 ASSERT( hashbin != NULL, return NULL;);
00499 ASSERT( hashbin->magic == HB_MAGIC, return NULL;);
00500
00501 if ( hashbin->hb_current == NULL) {
00502 ASSERT( hashbin->hb_current != NULL, return NULL;);
00503 return NULL;
00504 }
00505 entry = hashbin->hb_current->q_next;
00506 bin = GET_HASHBIN( entry->q_hash);
00507
00508
00509
00510
00511
00512 if ( entry != hashbin->hb_queue[ bin ]) {
00513 hashbin->hb_current = entry;
00514
00515 return entry;
00516 }
00517
00518
00519
00520
00521 if ( bin >= HASHBIN_SIZE)
00522 return NULL;
00523
00524
00525
00526
00527 bin++;
00528 for ( i = bin; i < HASHBIN_SIZE; i++ ) {
00529 entry = hashbin->hb_queue[ i];
00530 if ( entry) {
00531 hashbin->hb_current = entry;
00532
00533 return entry;
00534 }
00535 }
00536 return NULL;
00537 }
00538
00539
00540
00541
00542
00543
00544
00545 static void __enqueue_last( queue_t **queue, queue_t* element)
00546 {
00547 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
00548
00549
00550
00551
00552 if ( *queue == NULL ) {
00553
00554
00555
00556 element->q_next = element->q_prev = *queue = element;
00557
00558 } else {
00559
00560
00561
00562 element->q_prev = (*queue)->q_prev;
00563 element->q_prev->q_next = element;
00564 (*queue)->q_prev = element;
00565 element->q_next = *queue;
00566 }
00567 }
00568
00569 inline void enqueue_last( queue_t **queue, queue_t* element)
00570 {
00571 unsigned long flags;
00572
00573 save_flags(flags);
00574 cli();
00575
00576 __enqueue_last( queue, element);
00577
00578 restore_flags(flags);
00579 }
00580
00581
00582
00583
00584
00585
00586
00587 void enqueue_first(queue_t **queue, queue_t* element)
00588 {
00589
00590 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
00591
00592
00593
00594
00595 if ( *queue == NULL ) {
00596
00597
00598
00599 element->q_next = element->q_prev = *queue = element;
00600
00601 } else {
00602
00603
00604
00605 element->q_next = (*queue);
00606 (*queue)->q_prev->q_next = element;
00607 element->q_prev = (*queue)->q_prev;
00608 (*queue)->q_prev = element;
00609 (*queue) = element;
00610 }
00611 }
00612
00613
00614
00615
00616
00617
00618
00619 void enqueue_queue( queue_t** queue, queue_t** list )
00620 {
00621 queue_t* tmp;
00622
00623
00624
00625
00626 if ( *queue ) {
00627 (*list)->q_prev->q_next = (*queue);
00628 (*queue)->q_prev->q_next = (*list);
00629 tmp = (*list)->q_prev;
00630 (*list)->q_prev = (*queue)->q_prev;
00631 (*queue)->q_prev = tmp;
00632 } else {
00633 *queue = (*list);
00634 }
00635
00636 (*list) = NULL;
00637 }
00638
00639
00640
00641
00642
00643
00644
00645 #if 0
00646 static void enqueue_second(queue_t **queue, queue_t* element)
00647 {
00648 IRDA_DEBUG( 0, "enqueue_second()\n");
00649
00650
00651
00652
00653 if ( *queue == NULL ) {
00654
00655
00656
00657 element->q_next = element->q_prev = *queue = element;
00658
00659 } else {
00660
00661
00662
00663 element->q_prev = (*queue);
00664 (*queue)->q_next->q_prev = element;
00665 element->q_next = (*queue)->q_next;
00666 (*queue)->q_next = element;
00667 }
00668 }
00669 #endif
00670
00671
00672
00673
00674
00675
00676
00677 queue_t *dequeue_first(queue_t **queue)
00678 {
00679 queue_t *ret;
00680
00681 IRDA_DEBUG( 4, "dequeue_first()\n");
00682
00683
00684
00685
00686 ret = *queue;
00687
00688 if ( *queue == NULL ) {
00689
00690
00691
00692 } else if ( (*queue)->q_next == *queue ) {
00693
00694
00695
00696
00697 *queue = NULL;
00698 } else {
00699
00700
00701
00702 (*queue)->q_prev->q_next = (*queue)->q_next;
00703 (*queue)->q_next->q_prev = (*queue)->q_prev;
00704 *queue = (*queue)->q_next;
00705 }
00706
00707
00708
00709
00710 return ret;
00711 }
00712
00713
00714
00715
00716
00717
00718 static queue_t *dequeue_general(queue_t **queue, queue_t* element)
00719 {
00720 queue_t *ret;
00721
00722 IRDA_DEBUG( 4, "dequeue_general()\n");
00723
00724
00725
00726
00727 ret = *queue;
00728
00729 if ( *queue == NULL ) {
00730
00731
00732
00733 } if ( (*queue)->q_next == *queue ) {
00734
00735
00736
00737
00738 *queue = NULL;
00739
00740 } else {
00741
00742
00743
00744 element->q_prev->q_next = element->q_next;
00745 element->q_next->q_prev = element->q_prev;
00746 if ( (*queue) == element)
00747 (*queue) = element->q_next;
00748 }
00749
00750
00751
00752
00753 return ret;
00754 }
00755
00756
00757
00758
00759
00760
00761
00762 static __u32 hash( char* name)
00763 {
00764 __u32 h = 0;
00765 __u32 g;
00766
00767 while(*name) {
00768 h = (h<<4) + *name++;
00769 if ((g = (h & 0xf0000000)))
00770 h ^=g>>24;
00771 h &=~g;
00772 }
00773 return h;
00774 }