This source file includes following definitions.
- sci_remote_node_table_get_group_index
- sci_remote_node_table_clear_group_index
- sci_remote_node_table_set_group_index
- sci_remote_node_table_set_node_index
- sci_remote_node_table_clear_node_index
- sci_remote_node_table_clear_group
- sci_remote_node_table_set_group
- sci_remote_node_table_get_group_value
- sci_remote_node_table_initialize
- sci_remote_node_table_allocate_single_remote_node
- sci_remote_node_table_allocate_triple_remote_node
- sci_remote_node_table_allocate_remote_node
- sci_remote_node_table_release_single_remote_node
- sci_remote_node_table_release_triple_remote_node
- sci_remote_node_table_release_remote_node_index
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 #include "remote_node_table.h"
63 #include "remote_node_context.h"
64
65
66
67
68
69
70
71
72
73
74
75
76
77 static u32 sci_remote_node_table_get_group_index(
78 struct sci_remote_node_table *remote_node_table,
79 u32 group_table_index)
80 {
81 u32 dword_index;
82 u32 *group_table;
83 u32 bit_index;
84
85 group_table = remote_node_table->remote_node_groups[group_table_index];
86
87 for (dword_index = 0; dword_index < remote_node_table->group_array_size; dword_index++) {
88 if (group_table[dword_index] != 0) {
89 for (bit_index = 0; bit_index < 32; bit_index++) {
90 if ((group_table[dword_index] & (1 << bit_index)) != 0) {
91 return (dword_index * 32) + bit_index;
92 }
93 }
94 }
95 }
96
97 return SCIC_SDS_REMOTE_NODE_TABLE_INVALID_INDEX;
98 }
99
100
101
102
103
104
105
106
107
108
109
110
111 static void sci_remote_node_table_clear_group_index(
112 struct sci_remote_node_table *remote_node_table,
113 u32 group_table_index,
114 u32 group_index)
115 {
116 u32 dword_index;
117 u32 bit_index;
118 u32 *group_table;
119
120 BUG_ON(group_table_index >= SCU_STP_REMOTE_NODE_COUNT);
121 BUG_ON(group_index >= (u32)(remote_node_table->group_array_size * 32));
122
123 dword_index = group_index / 32;
124 bit_index = group_index % 32;
125 group_table = remote_node_table->remote_node_groups[group_table_index];
126
127 group_table[dword_index] = group_table[dword_index] & ~(1 << bit_index);
128 }
129
130
131
132
133
134
135
136
137
138
139
140
141 static void sci_remote_node_table_set_group_index(
142 struct sci_remote_node_table *remote_node_table,
143 u32 group_table_index,
144 u32 group_index)
145 {
146 u32 dword_index;
147 u32 bit_index;
148 u32 *group_table;
149
150 BUG_ON(group_table_index >= SCU_STP_REMOTE_NODE_COUNT);
151 BUG_ON(group_index >= (u32)(remote_node_table->group_array_size * 32));
152
153 dword_index = group_index / 32;
154 bit_index = group_index % 32;
155 group_table = remote_node_table->remote_node_groups[group_table_index];
156
157 group_table[dword_index] = group_table[dword_index] | (1 << bit_index);
158 }
159
160
161
162
163
164
165
166
167
168
169
170 static void sci_remote_node_table_set_node_index(
171 struct sci_remote_node_table *remote_node_table,
172 u32 remote_node_index)
173 {
174 u32 dword_location;
175 u32 dword_remainder;
176 u32 slot_normalized;
177 u32 slot_position;
178
179 BUG_ON(
180 (remote_node_table->available_nodes_array_size * SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD)
181 <= (remote_node_index / SCU_STP_REMOTE_NODE_COUNT)
182 );
183
184 dword_location = remote_node_index / SCIC_SDS_REMOTE_NODES_PER_DWORD;
185 dword_remainder = remote_node_index % SCIC_SDS_REMOTE_NODES_PER_DWORD;
186 slot_normalized = (dword_remainder / SCU_STP_REMOTE_NODE_COUNT) * sizeof(u32);
187 slot_position = remote_node_index % SCU_STP_REMOTE_NODE_COUNT;
188
189 remote_node_table->available_remote_nodes[dword_location] |=
190 1 << (slot_normalized + slot_position);
191 }
192
193
194
195
196
197
198
199
200
201
202
203 static void sci_remote_node_table_clear_node_index(
204 struct sci_remote_node_table *remote_node_table,
205 u32 remote_node_index)
206 {
207 u32 dword_location;
208 u32 dword_remainder;
209 u32 slot_position;
210 u32 slot_normalized;
211
212 BUG_ON(
213 (remote_node_table->available_nodes_array_size * SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD)
214 <= (remote_node_index / SCU_STP_REMOTE_NODE_COUNT)
215 );
216
217 dword_location = remote_node_index / SCIC_SDS_REMOTE_NODES_PER_DWORD;
218 dword_remainder = remote_node_index % SCIC_SDS_REMOTE_NODES_PER_DWORD;
219 slot_normalized = (dword_remainder / SCU_STP_REMOTE_NODE_COUNT) * sizeof(u32);
220 slot_position = remote_node_index % SCU_STP_REMOTE_NODE_COUNT;
221
222 remote_node_table->available_remote_nodes[dword_location] &=
223 ~(1 << (slot_normalized + slot_position));
224 }
225
226
227
228
229
230
231
232
233
234 static void sci_remote_node_table_clear_group(
235 struct sci_remote_node_table *remote_node_table,
236 u32 group_index)
237 {
238 u32 dword_location;
239 u32 dword_remainder;
240 u32 dword_value;
241
242 BUG_ON(
243 (remote_node_table->available_nodes_array_size * SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD)
244 <= (group_index / SCU_STP_REMOTE_NODE_COUNT)
245 );
246
247 dword_location = group_index / SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
248 dword_remainder = group_index % SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
249
250 dword_value = remote_node_table->available_remote_nodes[dword_location];
251 dword_value &= ~(SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE << (dword_remainder * 4));
252 remote_node_table->available_remote_nodes[dword_location] = dword_value;
253 }
254
255
256
257
258
259
260
261 static void sci_remote_node_table_set_group(
262 struct sci_remote_node_table *remote_node_table,
263 u32 group_index)
264 {
265 u32 dword_location;
266 u32 dword_remainder;
267 u32 dword_value;
268
269 BUG_ON(
270 (remote_node_table->available_nodes_array_size * SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD)
271 <= (group_index / SCU_STP_REMOTE_NODE_COUNT)
272 );
273
274 dword_location = group_index / SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
275 dword_remainder = group_index % SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
276
277 dword_value = remote_node_table->available_remote_nodes[dword_location];
278 dword_value |= (SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE << (dword_remainder * 4));
279 remote_node_table->available_remote_nodes[dword_location] = dword_value;
280 }
281
282
283
284
285
286
287
288
289
290
291 static u8 sci_remote_node_table_get_group_value(
292 struct sci_remote_node_table *remote_node_table,
293 u32 group_index)
294 {
295 u32 dword_location;
296 u32 dword_remainder;
297 u32 dword_value;
298
299 dword_location = group_index / SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
300 dword_remainder = group_index % SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
301
302 dword_value = remote_node_table->available_remote_nodes[dword_location];
303 dword_value &= (SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE << (dword_remainder * 4));
304 dword_value = dword_value >> (dword_remainder * 4);
305
306 return (u8)dword_value;
307 }
308
309
310
311
312
313
314
315
316 void sci_remote_node_table_initialize(
317 struct sci_remote_node_table *remote_node_table,
318 u32 remote_node_entries)
319 {
320 u32 index;
321
322
323
324
325 memset(
326 remote_node_table->available_remote_nodes,
327 0x00,
328 sizeof(remote_node_table->available_remote_nodes)
329 );
330
331 memset(
332 remote_node_table->remote_node_groups,
333 0x00,
334 sizeof(remote_node_table->remote_node_groups)
335 );
336
337
338 remote_node_table->available_nodes_array_size = (u16)
339 (remote_node_entries / SCIC_SDS_REMOTE_NODES_PER_DWORD)
340 + ((remote_node_entries % SCIC_SDS_REMOTE_NODES_PER_DWORD) != 0);
341
342
343
344 for (index = 0; index < remote_node_entries; index++) {
345 sci_remote_node_table_set_node_index(remote_node_table, index);
346 }
347
348 remote_node_table->group_array_size = (u16)
349 (remote_node_entries / (SCU_STP_REMOTE_NODE_COUNT * 32))
350 + ((remote_node_entries % (SCU_STP_REMOTE_NODE_COUNT * 32)) != 0);
351
352 for (index = 0; index < (remote_node_entries / SCU_STP_REMOTE_NODE_COUNT); index++) {
353
354
355
356 sci_remote_node_table_set_group_index(remote_node_table, 2, index);
357 }
358
359
360 if ((remote_node_entries % SCU_STP_REMOTE_NODE_COUNT) == 2) {
361 sci_remote_node_table_set_group_index(remote_node_table, 1, index);
362 } else if ((remote_node_entries % SCU_STP_REMOTE_NODE_COUNT) == 1) {
363 sci_remote_node_table_set_group_index(remote_node_table, 0, index);
364 }
365 }
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382 static u16 sci_remote_node_table_allocate_single_remote_node(
383 struct sci_remote_node_table *remote_node_table,
384 u32 group_table_index)
385 {
386 u8 index;
387 u8 group_value;
388 u32 group_index;
389 u16 remote_node_index = SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX;
390
391 group_index = sci_remote_node_table_get_group_index(
392 remote_node_table, group_table_index);
393
394
395 if (group_index != SCIC_SDS_REMOTE_NODE_TABLE_INVALID_INDEX) {
396 group_value = sci_remote_node_table_get_group_value(
397 remote_node_table, group_index);
398
399 for (index = 0; index < SCU_STP_REMOTE_NODE_COUNT; index++) {
400 if (((1 << index) & group_value) != 0) {
401
402 remote_node_index = (u16)(group_index * SCU_STP_REMOTE_NODE_COUNT
403 + index);
404
405 sci_remote_node_table_clear_group_index(
406 remote_node_table, group_table_index, group_index
407 );
408
409 sci_remote_node_table_clear_node_index(
410 remote_node_table, remote_node_index
411 );
412
413 if (group_table_index > 0) {
414 sci_remote_node_table_set_group_index(
415 remote_node_table, group_table_index - 1, group_index
416 );
417 }
418
419 break;
420 }
421 }
422 }
423
424 return remote_node_index;
425 }
426
427
428
429
430
431
432
433
434
435
436
437
438
439 static u16 sci_remote_node_table_allocate_triple_remote_node(
440 struct sci_remote_node_table *remote_node_table,
441 u32 group_table_index)
442 {
443 u32 group_index;
444 u16 remote_node_index = SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX;
445
446 group_index = sci_remote_node_table_get_group_index(
447 remote_node_table, group_table_index);
448
449 if (group_index != SCIC_SDS_REMOTE_NODE_TABLE_INVALID_INDEX) {
450 remote_node_index = (u16)group_index * SCU_STP_REMOTE_NODE_COUNT;
451
452 sci_remote_node_table_clear_group_index(
453 remote_node_table, group_table_index, group_index
454 );
455
456 sci_remote_node_table_clear_group(
457 remote_node_table, group_index
458 );
459 }
460
461 return remote_node_index;
462 }
463
464
465
466
467
468
469
470
471
472
473
474
475
476 u16 sci_remote_node_table_allocate_remote_node(
477 struct sci_remote_node_table *remote_node_table,
478 u32 remote_node_count)
479 {
480 u16 remote_node_index = SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX;
481
482 if (remote_node_count == SCU_SSP_REMOTE_NODE_COUNT) {
483 remote_node_index =
484 sci_remote_node_table_allocate_single_remote_node(
485 remote_node_table, 0);
486
487 if (remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) {
488 remote_node_index =
489 sci_remote_node_table_allocate_single_remote_node(
490 remote_node_table, 1);
491 }
492
493 if (remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) {
494 remote_node_index =
495 sci_remote_node_table_allocate_single_remote_node(
496 remote_node_table, 2);
497 }
498 } else if (remote_node_count == SCU_STP_REMOTE_NODE_COUNT) {
499 remote_node_index =
500 sci_remote_node_table_allocate_triple_remote_node(
501 remote_node_table, 2);
502 }
503
504 return remote_node_index;
505 }
506
507
508
509
510
511
512
513
514 static void sci_remote_node_table_release_single_remote_node(
515 struct sci_remote_node_table *remote_node_table,
516 u16 remote_node_index)
517 {
518 u32 group_index;
519 u8 group_value;
520
521 group_index = remote_node_index / SCU_STP_REMOTE_NODE_COUNT;
522
523 group_value = sci_remote_node_table_get_group_value(remote_node_table, group_index);
524
525
526
527
528 BUG_ON(group_value == SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE);
529
530 if (group_value == 0x00) {
531
532
533
534 sci_remote_node_table_set_group_index(remote_node_table, 0, group_index);
535 } else if ((group_value & (group_value - 1)) == 0) {
536
537
538
539 sci_remote_node_table_clear_group_index(remote_node_table, 0, group_index);
540 sci_remote_node_table_set_group_index(remote_node_table, 1, group_index);
541 } else {
542
543
544
545 sci_remote_node_table_clear_group_index(remote_node_table, 1, group_index);
546 sci_remote_node_table_set_group_index(remote_node_table, 2, group_index);
547 }
548
549 sci_remote_node_table_set_node_index(remote_node_table, remote_node_index);
550 }
551
552
553
554
555
556
557
558
559
560 static void sci_remote_node_table_release_triple_remote_node(
561 struct sci_remote_node_table *remote_node_table,
562 u16 remote_node_index)
563 {
564 u32 group_index;
565
566 group_index = remote_node_index / SCU_STP_REMOTE_NODE_COUNT;
567
568 sci_remote_node_table_set_group_index(
569 remote_node_table, 2, group_index
570 );
571
572 sci_remote_node_table_set_group(remote_node_table, group_index);
573 }
574
575
576
577
578
579
580
581
582
583
584
585 void sci_remote_node_table_release_remote_node_index(
586 struct sci_remote_node_table *remote_node_table,
587 u32 remote_node_count,
588 u16 remote_node_index)
589 {
590 if (remote_node_count == SCU_SSP_REMOTE_NODE_COUNT) {
591 sci_remote_node_table_release_single_remote_node(
592 remote_node_table, remote_node_index);
593 } else if (remote_node_count == SCU_STP_REMOTE_NODE_COUNT) {
594 sci_remote_node_table_release_triple_remote_node(
595 remote_node_table, remote_node_index);
596 }
597 }
598