2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
9 #include <linux/types.h>
10 #include <asm/sn/sgi.h>
11 #include <asm/sn/pci/pciio.h>
12 #include <asm/sn/pci/pcibr.h>
13 #include <asm/sn/pci/pcibr_private.h>
14 #include <asm/sn/pci/pci_defs.h>
16 void pcibr_rrb_alloc_init(pcibr_soft_t, int, int, int);
17 void pcibr_rrb_alloc_more(pcibr_soft_t, int, int, int);
19 int pcibr_wrb_flush(vertex_hdl_t);
20 int pcibr_rrb_alloc(vertex_hdl_t, int *, int *);
21 int pcibr_rrb_check(vertex_hdl_t, int *, int *, int *, int *);
22 int pcibr_alloc_all_rrbs(vertex_hdl_t, int, int, int, int,
23 int, int, int, int, int);
24 void pcibr_rrb_flush(vertex_hdl_t);
25 int pcibr_slot_initial_rrb_alloc(vertex_hdl_t,pciio_slot_t);
27 void pcibr_rrb_debug(char *, pcibr_soft_t);
33 * All the do_pcibr_rrb_ routines manipulate the Read Response Buffer (rrb)
34 * registers within the Bridge. Two 32 registers (b_rrb_map[2] also known
35 * as the b_even_resp & b_odd_resp registers) are used to allocate the 16
36 * rrbs to devices. The b_even_resp register represents even num devices,
37 * and b_odd_resp represent odd number devices. Each rrb is represented by
38 * 4-bits within a register.
39 * BRIDGE & XBRIDGE: 1 enable bit, 1 virtual channel bit, 2 device bits
40 * PIC: 1 enable bit, 2 virtual channel bits, 1 device bit
41 * PIC has 4 devices per bus, and 4 virtual channels (1 normal & 3 virtual)
42 * per device. BRIDGE & XBRIDGE have 8 devices per bus and 2 virtual
43 * channels (1 normal & 1 virtual) per device. See the BRIDGE and PIC ASIC
44 * Programmers Reference guides for more information.
47 #define RRB_MASK (0xf) /* mask a single rrb within reg */
48 #define RRB_SIZE (4) /* sizeof rrb within reg (bits) */
50 #define RRB_ENABLE_BIT (0x8) /* [BRIDGE | PIC]_RRB_EN */
51 #define NUM_PDEV_BITS (1)
52 #define NUMBER_VCHANNELS (4)
53 #define SLOT_2_PDEV(slot) ((slot) >> 1)
54 #define SLOT_2_RRB_REG(slot) ((slot) & 0x1)
56 #define RRB_VALID(rrb) (0x00010000 << (rrb))
57 #define RRB_INUSE(rrb) (0x00000001 << (rrb))
58 #define RRB_CLEAR(rrb) (0x00000001 << (rrb))
60 /* validate that the slot and virtual channel are valid */
61 #define VALIDATE_SLOT_n_VCHAN(s, v) \
62 (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)3)) && \
63 (((v) >= 0) && ((v) <= 3))) ? 1 : 0)
66 * Count how many RRBs are marked valid for the specified PCI slot
67 * and virtual channel. Return the count.
70 do_pcibr_rrb_count_valid(pcibr_soft_t pcibr_soft,
75 uint16_t enable_bit, vchan_bits, pdev_bits, rrb_bits;
78 if (!VALIDATE_SLOT_n_VCHAN(slot, vchan)) {
79 printk(KERN_WARNING "do_pcibr_rrb_count_valid() invalid slot/vchan [%d/%d]\n", slot, vchan);
83 enable_bit = RRB_ENABLE_BIT;
84 vchan_bits = vchan << NUM_PDEV_BITS;
85 pdev_bits = SLOT_2_PDEV(slot);
86 rrb_bits = enable_bit | vchan_bits | pdev_bits;
88 tmp = pcireg_rrb_get(pcibr_soft, SLOT_2_RRB_REG(slot));
90 for (rrb_index = 0; rrb_index < 8; rrb_index++) {
91 if ((tmp & RRB_MASK) == rrb_bits)
93 tmp = (tmp >> RRB_SIZE);
100 * Count how many RRBs are available to be allocated to the specified
101 * slot. Return the count.
104 do_pcibr_rrb_count_avail(pcibr_soft_t pcibr_soft,
109 int rrb_index, cnt=0;
111 if (!VALIDATE_SLOT_n_VCHAN(slot, 0)) {
112 printk(KERN_WARNING "do_pcibr_rrb_count_avail() invalid slot/vchan");
116 enable_bit = RRB_ENABLE_BIT;
118 tmp = pcireg_rrb_get(pcibr_soft, SLOT_2_RRB_REG(slot));
120 for (rrb_index = 0; rrb_index < 8; rrb_index++) {
121 if ((tmp & enable_bit) != enable_bit)
123 tmp = (tmp >> RRB_SIZE);
130 * Allocate some additional RRBs for the specified slot and the specified
131 * virtual channel. Returns -1 if there were insufficient free RRBs to
132 * satisfy the request, or 0 if the request was fulfilled.
134 * Note that if a request can be partially filled, it will be, even if
138 do_pcibr_rrb_alloc(pcibr_soft_t pcibr_soft,
143 uint64_t reg, tmp = 0;
144 uint16_t enable_bit, vchan_bits, pdev_bits, rrb_bits;
147 if (!VALIDATE_SLOT_n_VCHAN(slot, vchan)) {
148 printk(KERN_WARNING "do_pcibr_rrb_alloc() invalid slot/vchan");
152 enable_bit = RRB_ENABLE_BIT;
153 vchan_bits = vchan << NUM_PDEV_BITS;
154 pdev_bits = SLOT_2_PDEV(slot);
155 rrb_bits = enable_bit | vchan_bits | pdev_bits;
157 reg = tmp = pcireg_rrb_get(pcibr_soft, SLOT_2_RRB_REG(slot));
159 for (rrb_index = 0; ((rrb_index < 8) && (more > 0)); rrb_index++) {
160 if ((tmp & enable_bit) != enable_bit) {
161 /* clear the rrb and OR in the new rrb into 'reg' */
162 reg = reg & ~(RRB_MASK << (RRB_SIZE * rrb_index));
163 reg = reg | (rrb_bits << (RRB_SIZE * rrb_index));
166 tmp = (tmp >> RRB_SIZE);
169 pcireg_rrb_set(pcibr_soft, SLOT_2_RRB_REG(slot), reg);
170 return (more ? -1 : 0);
174 * Wait for the the specified rrb to have no outstanding XIO pkts
175 * and for all data to be drained. Mark the rrb as no longer being
179 do_pcibr_rrb_clear(pcibr_soft_t pcibr_soft, int rrb)
183 /* bridge_lock must be held; this RRB must be disabled. */
185 /* wait until RRB has no outstanduing XIO packets. */
186 status = pcireg_rrb_status_get(pcibr_soft);
187 while (status & RRB_INUSE(rrb)) {
188 status = pcireg_rrb_status_get(pcibr_soft);
191 /* if the RRB has data, drain it. */
192 if (status & RRB_VALID(rrb)) {
193 pcireg_rrb_clear_set(pcibr_soft, RRB_CLEAR(rrb));
195 /* wait until RRB is no longer valid. */
196 status = pcireg_rrb_status_get(pcibr_soft);
197 while (status & RRB_VALID(rrb)) {
198 status = pcireg_rrb_status_get(pcibr_soft);
205 * Release some of the RRBs that have been allocated for the specified
206 * slot. Returns zero for success, or negative if it was unable to free
209 * Note that if a request can be partially fulfilled, it will be, even
210 * if we return failure.
213 do_pcibr_rrb_free(pcibr_soft_t pcibr_soft,
218 uint64_t reg, tmp = 0, clr = 0;
219 uint16_t enable_bit, vchan_bits, pdev_bits, rrb_bits;
222 if (!VALIDATE_SLOT_n_VCHAN(slot, vchan)) {
223 printk(KERN_WARNING "do_pcibr_rrb_free() invalid slot/vchan");
227 enable_bit = RRB_ENABLE_BIT;
228 vchan_bits = vchan << NUM_PDEV_BITS;
229 pdev_bits = SLOT_2_PDEV(slot);
230 rrb_bits = enable_bit | vchan_bits | pdev_bits;
232 reg = tmp = pcireg_rrb_get(pcibr_soft, SLOT_2_RRB_REG(slot));
234 for (rrb_index = 0; ((rrb_index < 8) && (less > 0)); rrb_index++) {
235 if ((tmp & RRB_MASK) == rrb_bits) {
237 * the old do_pcibr_rrb_free() code only clears the enable bit
238 * but I say we should clear the whole rrb (ie):
239 * reg = reg & ~(RRB_MASK << (RRB_SIZE * rrb_index));
240 * But to be compatible with old code we'll only clear enable.
242 reg = reg & ~(RRB_ENABLE_BIT << (RRB_SIZE * rrb_index));
243 clr = clr | (enable_bit << (RRB_SIZE * rrb_index));
246 tmp = (tmp >> RRB_SIZE);
249 pcireg_rrb_set(pcibr_soft, SLOT_2_RRB_REG(slot), reg);
251 /* call do_pcibr_rrb_clear() for all the rrbs we've freed */
252 for (rrb_index = 0; rrb_index < 8; rrb_index++) {
253 int evn_odd = SLOT_2_RRB_REG(slot);
254 if (clr & (enable_bit << (RRB_SIZE * rrb_index)))
255 do_pcibr_rrb_clear(pcibr_soft, (2 * rrb_index) + evn_odd);
258 return (less ? -1 : 0);
262 * Flush the specified rrb by calling do_pcibr_rrb_clear(). This
263 * routine is just a wrapper to make sure the rrb is disabled
264 * before calling do_pcibr_rrb_clear().
267 do_pcibr_rrb_flush(pcibr_soft_t pcibr_soft, int rrbn)
270 int shft = (RRB_SIZE * (rrbn >> 1));
271 uint64_t ebit = RRB_ENABLE_BIT << shft;
273 rrbv = pcireg_rrb_get(pcibr_soft, (rrbn & 1));
275 pcireg_rrb_set(pcibr_soft, (rrbn & 1), (rrbv & ~ebit));
278 do_pcibr_rrb_clear(pcibr_soft, rrbn);
281 pcireg_rrb_set(pcibr_soft, (rrbn & 1), rrbv);
286 * free all the rrbs (both the normal and virtual channels) for the
290 do_pcibr_rrb_free_all(pcibr_soft_t pcibr_soft,
294 int vchan_total = NUMBER_VCHANNELS;
296 /* pretend we own all 8 rrbs and just ignore the return value */
297 for (vchan = 0; vchan < vchan_total; vchan++) {
298 do_pcibr_rrb_free(pcibr_soft, slot, vchan, 8);
299 pcibr_soft->bs_rrb_valid[slot][vchan] = 0;
305 * Initialize a slot with a given number of RRBs. (this routine
306 * will also give back RRBs if the slot has more than we want).
309 pcibr_rrb_alloc_init(pcibr_soft_t pcibr_soft,
314 int had = pcibr_soft->bs_rrb_valid[slot][vchan];
318 for (added = 0; have < init_rrbs; ++added, ++have) {
319 if (pcibr_soft->bs_rrb_res[slot] > 0)
320 pcibr_soft->bs_rrb_res[slot]--;
321 else if (pcibr_soft->bs_rrb_avail[slot & 1] > 0)
322 pcibr_soft->bs_rrb_avail[slot & 1]--;
325 if (do_pcibr_rrb_alloc(pcibr_soft, slot, vchan, 1) < 0)
328 pcibr_soft->bs_rrb_valid[slot][vchan]++;
331 /* Free any extra RRBs that the slot may have allocated to it */
332 while (have > init_rrbs) {
333 pcibr_soft->bs_rrb_avail[slot & 1]++;
334 pcibr_soft->bs_rrb_valid[slot][vchan]--;
335 do_pcibr_rrb_free(pcibr_soft, slot, vchan, 1);
340 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_soft->bs_vhdl,
341 "pcibr_rrb_alloc_init: had %d, added/removed %d, "
342 "(of requested %d) RRBs "
343 "to slot %d, vchan %d\n", had, added, init_rrbs,
344 PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), vchan));
346 pcibr_rrb_debug("pcibr_rrb_alloc_init", pcibr_soft);
351 * Allocate more RRBs to a given slot (if the RRBs are available).
354 pcibr_rrb_alloc_more(pcibr_soft_t pcibr_soft,
361 for (added = 0; added < more_rrbs; ++added) {
362 if (pcibr_soft->bs_rrb_res[slot] > 0)
363 pcibr_soft->bs_rrb_res[slot]--;
364 else if (pcibr_soft->bs_rrb_avail[slot & 1] > 0)
365 pcibr_soft->bs_rrb_avail[slot & 1]--;
368 if (do_pcibr_rrb_alloc(pcibr_soft, slot, vchan, 1) < 0)
371 pcibr_soft->bs_rrb_valid[slot][vchan]++;
374 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_soft->bs_vhdl,
375 "pcibr_rrb_alloc_more: added %d (of %d requested) RRBs "
376 "to slot %d, vchan %d\n", added, more_rrbs,
377 PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), vchan));
379 pcibr_rrb_debug("pcibr_rrb_alloc_more", pcibr_soft);
384 * Flush all the rrb's assigned to the specified connection point.
387 pcibr_rrb_flush(vertex_hdl_t pconn_vhdl)
389 pciio_info_t pciio_info = pciio_info_get(pconn_vhdl);
390 pcibr_soft_t pcibr_soft = (pcibr_soft_t)pciio_info_mfast_get(pciio_info);
391 pciio_slot_t slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
394 uint16_t enable_bit, pdev_bits, rrb_bits, rrb_mask;
398 enable_bit = RRB_ENABLE_BIT;
399 pdev_bits = SLOT_2_PDEV(slot);
400 rrb_bits = enable_bit | pdev_bits;
401 rrb_mask = enable_bit | ((NUM_PDEV_BITS << 1) - 1);
403 tmp = pcireg_rrb_get(pcibr_soft, SLOT_2_RRB_REG(slot));
405 s = pcibr_lock(pcibr_soft);
406 for (rrb_index = 0; rrb_index < 8; rrb_index++) {
407 int evn_odd = SLOT_2_RRB_REG(slot);
408 if ((tmp & rrb_mask) == rrb_bits)
409 do_pcibr_rrb_flush(pcibr_soft, (2 * rrb_index) + evn_odd);
410 tmp = (tmp >> RRB_SIZE);
412 pcibr_unlock(pcibr_soft, s);
417 * Device driver interface to flush the write buffers for a specified
418 * device hanging off the bridge.
421 pcibr_wrb_flush(vertex_hdl_t pconn_vhdl)
423 pciio_info_t pciio_info = pciio_info_get(pconn_vhdl);
424 pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
425 pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
427 pcireg_wrb_flush_get(pcibr_soft, pciio_slot);
433 * Device driver interface to request RRBs for a specified device
434 * hanging off a Bridge. The driver requests the total number of
435 * RRBs it would like for the normal channel (vchan0) and for the
436 * "virtual channel" (vchan1). The actual number allocated to each
437 * channel is returned.
439 * If we cannot allocate at least one RRB to a channel that needs
440 * at least one, return -1 (failure). Otherwise, satisfy the request
441 * as best we can and return 0.
444 pcibr_rrb_alloc(vertex_hdl_t pconn_vhdl,
448 pciio_info_t pciio_info = pciio_info_get(pconn_vhdl);
449 pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
450 pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
467 * TBD: temper request with admin info about RRB allocation,
468 * and according to demand from other devices on this Bridge.
470 * One way of doing this would be to allocate two RRBs
471 * for each device on the bus, before any drivers start
472 * asking for extras. This has the weakness that one
473 * driver might not give back an "extra" RRB until after
474 * another driver has already failed to get one that
478 s = pcibr_lock(pcibr_soft);
480 vchan_total = NUMBER_VCHANNELS;
482 /* Save the boot-time RRB configuration for this slot */
483 if (pcibr_soft->bs_rrb_valid_dflt[pciio_slot][VCHAN0] < 0) {
484 for (vchan = 0; vchan < vchan_total; vchan++)
485 pcibr_soft->bs_rrb_valid_dflt[pciio_slot][vchan] =
486 pcibr_soft->bs_rrb_valid[pciio_slot][vchan];
487 pcibr_soft->bs_rrb_res_dflt[pciio_slot] =
488 pcibr_soft->bs_rrb_res[pciio_slot];
492 /* How many RRBs do we own? */
493 orig_vchan0 = pcibr_soft->bs_rrb_valid[pciio_slot][VCHAN0];
494 orig_vchan1 = pcibr_soft->bs_rrb_valid[pciio_slot][VCHAN1];
496 /* How many RRBs do we want? */
497 desired_vchan0 = count_vchan0 ? *count_vchan0 : orig_vchan0;
498 desired_vchan1 = count_vchan1 ? *count_vchan1 : orig_vchan1;
500 /* How many RRBs are free? */
501 avail_rrbs = pcibr_soft->bs_rrb_avail[pciio_slot & 1]
502 + pcibr_soft->bs_rrb_res[pciio_slot];
504 /* Figure desired deltas */
505 delta_vchan0 = desired_vchan0 - orig_vchan0;
506 delta_vchan1 = desired_vchan1 - orig_vchan1;
508 /* Trim back deltas to something
509 * that we can actually meet, by
510 * decreasing the ending allocation
511 * for whichever channel wants
512 * more RRBs. If both want the same
513 * number, cut the second channel.
514 * NOTE: do not change the allocation for
515 * a channel that was passed as NULL.
517 while ((delta_vchan0 + delta_vchan1) > avail_rrbs) {
520 ((orig_vchan0 + delta_vchan0) >
521 (orig_vchan1 + delta_vchan1))))
527 /* Figure final RRB allocations
529 final_vchan0 = orig_vchan0 + delta_vchan0;
530 final_vchan1 = orig_vchan1 + delta_vchan1;
532 /* If either channel wants RRBs but our actions
533 * would leave it with none, declare an error,
534 * but DO NOT change any RRB allocations.
536 if ((desired_vchan0 && !final_vchan0) ||
537 (desired_vchan1 && !final_vchan1)) {
543 /* Commit the allocations: free, then alloc.
545 if (delta_vchan0 < 0)
546 do_pcibr_rrb_free(pcibr_soft, pciio_slot, VCHAN0, -delta_vchan0);
547 if (delta_vchan1 < 0)
548 do_pcibr_rrb_free(pcibr_soft, pciio_slot, VCHAN1, -delta_vchan1);
550 if (delta_vchan0 > 0)
551 do_pcibr_rrb_alloc(pcibr_soft, pciio_slot, VCHAN0, delta_vchan0);
552 if (delta_vchan1 > 0)
553 do_pcibr_rrb_alloc(pcibr_soft, pciio_slot, VCHAN1, delta_vchan1);
555 /* Return final values to caller.
558 *count_vchan0 = final_vchan0;
560 *count_vchan1 = final_vchan1;
562 /* prevent automatic changes to this slot's RRBs
564 pcibr_soft->bs_rrb_fixed |= 1 << pciio_slot;
566 /* Track the actual allocations, release
567 * any further reservations, and update the
568 * number of available RRBs.
571 pcibr_soft->bs_rrb_valid[pciio_slot][VCHAN0] = final_vchan0;
572 pcibr_soft->bs_rrb_valid[pciio_slot][VCHAN1] = final_vchan1;
573 pcibr_soft->bs_rrb_avail[pciio_slot & 1] =
574 pcibr_soft->bs_rrb_avail[pciio_slot & 1]
575 + pcibr_soft->bs_rrb_res[pciio_slot]
578 pcibr_soft->bs_rrb_res[pciio_slot] = 0;
581 * Reserve enough RRBs so this slot's RRB configuration can be
582 * reset to its boot-time default following a hot-plug shut-down
584 res_rrbs = (pcibr_soft->bs_rrb_res_dflt[pciio_slot] -
585 pcibr_soft->bs_rrb_res[pciio_slot]);
586 for (vchan = 0; vchan < vchan_total; vchan++) {
587 res_rrbs += (pcibr_soft->bs_rrb_valid_dflt[pciio_slot][vchan] -
588 pcibr_soft->bs_rrb_valid[pciio_slot][vchan]);
592 pcibr_soft->bs_rrb_res[pciio_slot] = res_rrbs;
593 pcibr_soft->bs_rrb_avail[pciio_slot & 1] =
594 pcibr_soft->bs_rrb_avail[pciio_slot & 1]
598 pcibr_rrb_debug("pcibr_rrb_alloc", pcibr_soft);
603 pcibr_unlock(pcibr_soft, s);
609 * Device driver interface to check the current state
610 * of the RRB allocations.
612 * pconn_vhdl is your PCI connection point (specifies which
613 * PCI bus and which slot).
615 * count_vchan0 points to where to return the number of RRBs
616 * assigned to the primary DMA channel, used by all DMA
617 * that does not explicitly ask for the alternate virtual
620 * count_vchan1 points to where to return the number of RRBs
621 * assigned to the secondary DMA channel, used when
622 * PCIBR_VCHAN1 and PCIIO_DMA_A64 are specified.
624 * count_reserved points to where to return the number of RRBs
625 * that have been automatically reserved for your device at
626 * startup, but which have not been assigned to a
627 * channel. RRBs must be assigned to a channel to be used;
628 * this can be done either with an explicit pcibr_rrb_alloc
629 * call, or automatically by the infrastructure when a DMA
630 * translation is constructed. Any call to pcibr_rrb_alloc
631 * will release any unassigned reserved RRBs back to the
634 * count_pool points to where to return the number of RRBs
635 * that are currently unassigned and unreserved. This
636 * number can (and will) change as other drivers make calls
637 * to pcibr_rrb_alloc, or automatically allocate RRBs for
638 * DMA beyond their initial reservation.
640 * NULL may be passed for any of the return value pointers
641 * the caller is not interested in.
643 * The return value is "0" if all went well, or "-1" if
644 * there is a problem. Additionally, if the wrong vertex
645 * is passed in, one of the subsidiary support functions
646 * could panic with a "bad pciio fingerprint."
650 pcibr_rrb_check(vertex_hdl_t pconn_vhdl,
656 pciio_info_t pciio_info;
657 pciio_slot_t pciio_slot;
658 pcibr_soft_t pcibr_soft;
662 if ((pciio_info = pciio_info_get(pconn_vhdl)) &&
663 (pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info)) &&
664 ((pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info)) < PCIBR_NUM_SLOTS(pcibr_soft))) {
666 s = pcibr_lock(pcibr_soft);
670 pcibr_soft->bs_rrb_valid[pciio_slot][VCHAN0];
674 pcibr_soft->bs_rrb_valid[pciio_slot][VCHAN1];
678 pcibr_soft->bs_rrb_res[pciio_slot];
682 pcibr_soft->bs_rrb_avail[pciio_slot & 1];
686 pcibr_unlock(pcibr_soft, s);
692 * pcibr_slot_initial_rrb_alloc
693 * Allocate a default number of rrbs for this slot on
694 * the two channels. This is dictated by the rrb allocation
695 * strategy routine defined per platform.
699 pcibr_slot_initial_rrb_alloc(vertex_hdl_t pcibr_vhdl,
702 pcibr_soft_t pcibr_soft;
703 pcibr_info_h pcibr_infoh;
704 pcibr_info_t pcibr_info;
709 pcibr_soft = pcibr_soft_get(pcibr_vhdl);
714 if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
717 /* How many RRBs are on this slot? */
718 vchan_total = NUMBER_VCHANNELS;
719 for (vchan = 0; vchan < vchan_total; vchan++)
720 chan[vchan] = do_pcibr_rrb_count_valid(pcibr_soft, slot, vchan);
722 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_vhdl,
723 "pcibr_slot_initial_rrb_alloc: slot %d started with %d+%d+%d+%d\n",
724 PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot),
725 chan[VCHAN0], chan[VCHAN1], chan[VCHAN2], chan[VCHAN3]));
727 /* Do we really need any?
729 pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
730 pcibr_info = pcibr_infoh[0];
732 * PIC BRINGUP WAR (PV# 856866, 859504, 861476, 861478):
733 * Don't free RRBs we allocated to device[2|3]--vchan3 as
734 * a WAR to those PVs mentioned above. In pcibr_attach2
735 * we allocate RRB0,8,1,9 to device[2|3]--vchan3.
737 if (PCIBR_WAR_ENABLED(PV856866, pcibr_soft) &&
738 (slot == 2 || slot == 3) &&
739 (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) &&
740 !pcibr_soft->bs_slot[slot].has_host) {
742 for (vchan = 0; vchan < 2; vchan++) {
743 do_pcibr_rrb_free(pcibr_soft, slot, vchan, 8);
744 pcibr_soft->bs_rrb_valid[slot][vchan] = 0;
747 pcibr_soft->bs_rrb_valid[slot][3] = chan[3];
752 if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) &&
753 !pcibr_soft->bs_slot[slot].has_host) {
754 do_pcibr_rrb_free_all(pcibr_soft, slot);
756 /* Reserve RRBs for this empty slot for hot-plug */
757 for (vchan = 0; vchan < vchan_total; vchan++)
758 pcibr_soft->bs_rrb_valid[slot][vchan] = 0;
763 for (vchan = 0; vchan < vchan_total; vchan++)
764 pcibr_soft->bs_rrb_valid[slot][vchan] = chan[vchan];
772 * Assign an equal total number of RRBs to all candidate slots,
773 * where the total is the sum of the number of RRBs assigned to
774 * the normal channel, the number of RRBs assigned to the virtual
775 * channels, and the number of RRBs assigned as reserved.
777 * A candidate slot is any existing (populated or empty) slot.
778 * Empty SN1 slots need RRBs to support hot-plug operations.
782 pcibr_initial_rrb(vertex_hdl_t pcibr_vhdl,
783 pciio_slot_t first, pciio_slot_t last)
785 pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl);
794 have[0][0] = have[0][1] = have[0][2] = 0;
795 have[1][0] = have[1][1] = have[1][2] = 0;
798 vchan_total = NUMBER_VCHANNELS;
800 for (slot = pcibr_soft->bs_min_slot;
801 slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
802 /* Initial RRB management; give back RRBs in all non-existent slots */
803 pcibr_slot_initial_rrb_alloc(pcibr_vhdl, slot);
805 /* Base calculations only on existing slots */
806 if ((slot >= first) && (slot <= last)) {
808 for (vchan = 0; vchan < vchan_total; vchan++)
809 rrb_total += pcibr_soft->bs_rrb_valid[slot][vchan];
812 have[slot & 1][rrb_total]++;
816 /* Initialize even/odd slot available RRB counts */
817 pcibr_soft->bs_rrb_avail[0] = do_pcibr_rrb_count_avail(pcibr_soft, 0);
818 pcibr_soft->bs_rrb_avail[1] = do_pcibr_rrb_count_avail(pcibr_soft, 1);
821 * Calculate reserved RRBs for slots based on current RRB usage
823 for (eo = 0; eo < 2; eo++) {
824 if ((3 * have[eo][0] + 2 * have[eo][1] + have[eo][2]) <= pcibr_soft->bs_rrb_avail[eo])
826 else if ((2 * have[eo][0] + have[eo][1]) <= pcibr_soft->bs_rrb_avail[eo])
828 else if (have[eo][0] <= pcibr_soft->bs_rrb_avail[eo])
835 /* Assign reserved RRBs to existing slots */
836 for (slot = first; slot <= last; ++slot) {
839 if (pcibr_soft->bs_unused_slot & (1 << slot))
843 for (vchan = 0; vchan < vchan_total; vchan++)
844 rrb_total += pcibr_soft->bs_rrb_valid[slot][vchan];
846 r = res[slot & 1] - (rrb_total);
849 pcibr_soft->bs_rrb_res[slot] = r;
850 pcibr_soft->bs_rrb_avail[slot & 1] -= r;
854 pcibr_rrb_debug("pcibr_initial_rrb", pcibr_soft);
861 * Dump the pcibr_soft_t RRB state variable
864 pcibr_rrb_debug(char *calling_func, pcibr_soft_t pcibr_soft)
868 if (pcibr_debug_mask & PCIBR_DEBUG_RRB) {
869 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_soft->bs_vhdl,
870 "%s: rrbs available, even=%d, odd=%d\n", calling_func,
871 pcibr_soft->bs_rrb_avail[0], pcibr_soft->bs_rrb_avail[1]));
873 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_soft->bs_vhdl,
874 "\tslot\tvchan0\tvchan1\tvchan2\tvchan3\treserved\n"));
876 for (slot=0; slot < PCIBR_NUM_SLOTS(pcibr_soft); slot++) {
877 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_soft->bs_vhdl,
878 "\t %d\t %d\t %d\t %d\t %d\t %d\n",
879 PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot),
880 0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN0],
881 0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN1],
882 0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN2],
883 0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN3],
884 pcibr_soft->bs_rrb_res[slot]));