1/*
2 *
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License.  See the file "COPYING" in the main directory of this archive
5 * for more details.
6 *
7 * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
8 */
9
10#include <linux/types.h>
11#include <linux/slab.h>
12#include <linux/module.h>
13#include <asm/sn/sgi.h>
14#include <asm/sn/sn_cpuid.h>
15#include <asm/sn/addrs.h>
16#include <asm/sn/arch.h>
17#include <asm/sn/iograph.h>
18#include <asm/sn/invent.h>
19#include <asm/sn/hcl.h>
20#include <asm/sn/labelcl.h>
21#include <asm/sn/xtalk/xwidget.h>
22#include <asm/sn/pci/bridge.h>
23#include <asm/sn/pci/pciio.h>
24#include <asm/sn/pci/pcibr.h>
25#include <asm/sn/pci/pcibr_private.h>
26#include <asm/sn/pci/pci_defs.h>
27#include <asm/sn/prio.h>
28#include <asm/sn/xtalk/xbow.h>
29#include <asm/sn/ioc3.h>
30#include <asm/sn/eeprom.h>
31#include <asm/sn/io.h>
32#include <asm/sn/sn_private.h>
33
34void              do_pcibr_rrb_clear(bridge_t *, int);
35void              do_pcibr_rrb_flush(bridge_t *, int);
36int               do_pcibr_rrb_count_valid(bridge_t *, pciio_slot_t);
37int               do_pcibr_rrb_count_avail(bridge_t *, pciio_slot_t);
38int               do_pcibr_rrb_alloc(bridge_t *, pciio_slot_t, int);
39int               do_pcibr_rrb_free(bridge_t *, pciio_slot_t, int);
40
41void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int);
42
43int		  pcibr_wrb_flush(devfs_handle_t);
44int               pcibr_rrb_alloc(devfs_handle_t, int *, int *);
45int               pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *);
46int               pcibr_alloc_all_rrbs(devfs_handle_t, int, int, int, int, int, int, int, int, int);
47void              pcibr_rrb_flush(devfs_handle_t);
48int		  pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
49
50/*
51 *    RRB Management
52 */
53
54#define LSBIT(word)		((word) &~ ((word)-1))
55
56void
57do_pcibr_rrb_clear(bridge_t *bridge, int rrb)
58{
59    bridgereg_t             status;
60
61    /* bridge_lock must be held;
62     * this RRB must be disabled.
63     */
64
65    /* wait until RRB has no outstanduing XIO packets. */
66    while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
67	;
68    }
69
70    /* if the RRB has data, drain it. */
71    if (status & BRIDGE_RRB_VALID(rrb)) {
72	bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
73
74	/* wait until RRB is no longer valid. */
75	while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
76	    ;
77	}
78    }
79}
80
81void
82do_pcibr_rrb_flush(bridge_t *bridge, int rrbn)
83{
84    reg_p                   rrbp = &bridge->b_rrb_map[rrbn & 1].reg;
85    bridgereg_t             rrbv;
86    int                     shft = 4 * (rrbn >> 1);
87    unsigned                ebit = BRIDGE_RRB_EN << shft;
88
89    rrbv = *rrbp;
90    if (rrbv & ebit)
91	*rrbp = rrbv & ~ebit;
92
93    do_pcibr_rrb_clear(bridge, rrbn);
94
95    if (rrbv & ebit)
96	*rrbp = rrbv;
97}
98
99/*
100 *    pcibr_rrb_count_valid: count how many RRBs are
101 *      marked valid for the specified PCI slot on this
102 *      bridge.
103 *
104 *      NOTE: The "slot" parameter for all pcibr_rrb
105 *      management routines must include the "virtual"
106 *      bit; when manageing both the normal and the
107 *      virtual channel, separate calls to these
108 *      routines must be made. To denote the virtual
109 *      channel, add PCIBR_RRB_SLOT_VIRTUAL to the slot
110 *      number.
111 *
112 *      IMPL NOTE: The obvious algorithm is to iterate
113 *      through the RRB fields, incrementing a count if
114 *      the RRB is valid and matches the slot. However,
115 *      it is much simpler to use an algorithm derived
116 *      from the "partitioned add" idea. First, XOR in a
117 *      pattern such that the fields that match this
118 *      slot come up "all ones" and all other fields
119 *      have zeros in the mismatching bits. Then AND
120 *      together the bits in the field, so we end up
121 *      with one bit turned on for each field that
122 *      matched. Now we need to count these bits. This
123 *      can be done either with a series of shift/add
124 *      instructions or by using "tmp % 15"; I expect
125 *      that the cascaded shift/add will be faster.
126 */
127
128int
129do_pcibr_rrb_count_valid(bridge_t *bridge,
130			 pciio_slot_t slot)
131{
132    bridgereg_t             tmp;
133
134    tmp = bridge->b_rrb_map[slot & 1].reg;
135    tmp ^= 0x11111111 * (7 - slot / 2);
136    tmp &= (0xCCCCCCCC & tmp) >> 2;
137    tmp &= (0x22222222 & tmp) >> 1;
138    tmp += tmp >> 4;
139    tmp += tmp >> 8;
140    tmp += tmp >> 16;
141    return tmp & 15;
142}
143
144/*
145 *    do_pcibr_rrb_count_avail: count how many RRBs are
146 *      available to be allocated for the specified slot.
147 *
148 *      IMPL NOTE: similar to the above, except we are
149 *      just counting how many fields have the valid bit
150 *      turned off.
151 */
152int
153do_pcibr_rrb_count_avail(bridge_t *bridge,
154			 pciio_slot_t slot)
155{
156    bridgereg_t             tmp;
157
158    tmp = bridge->b_rrb_map[slot & 1].reg;
159    tmp = (0x88888888 & ~tmp) >> 3;
160    tmp += tmp >> 4;
161    tmp += tmp >> 8;
162    tmp += tmp >> 16;
163    return tmp & 15;
164}
165
166/*
167 *    do_pcibr_rrb_alloc: allocate some additional RRBs
168 *      for the specified slot. Returns -1 if there were
169 *      insufficient free RRBs to satisfy the request,
170 *      or 0 if the request was fulfilled.
171 *
172 *      Note that if a request can be partially filled,
173 *      it will be, even if we return failure.
174 *
175 *      IMPL NOTE: again we avoid iterating across all
176 *      the RRBs; instead, we form up a word containing
177 *      one bit for each free RRB, then peel the bits
178 *      off from the low end.
179 */
180int
181do_pcibr_rrb_alloc(bridge_t *bridge,
182		   pciio_slot_t slot,
183		   int more)
184{
185    int                     rv = 0;
186    bridgereg_t             reg, tmp, bit;
187
188    reg = bridge->b_rrb_map[slot & 1].reg;
189    tmp = (0x88888888 & ~reg) >> 3;
190    while (more-- > 0) {
191	bit = LSBIT(tmp);
192	if (!bit) {
193	    rv = -1;
194	    break;
195	}
196	tmp &= ~bit;
197	reg = ((reg & ~(bit * 15)) | (bit * (8 + slot / 2)));
198    }
199    bridge->b_rrb_map[slot & 1].reg = reg;
200    return rv;
201}
202
203/*
204 *    do_pcibr_rrb_free: release some of the RRBs that
205 *      have been allocated for the specified
206 *      slot. Returns zero for success, or negative if
207 *      it was unable to free that many RRBs.
208 *
209 *      IMPL NOTE: We form up a bit for each RRB
210 *      allocated to the slot, aligned with the VALID
211 *      bitfield this time; then we peel bits off one at
212 *      a time, releasing the corresponding RRB.
213 */
214int
215do_pcibr_rrb_free(bridge_t *bridge,
216		  pciio_slot_t slot,
217		  int less)
218{
219    int                     rv = 0;
220    bridgereg_t             reg, tmp, clr, bit;
221    int                     i;
222
223    clr = 0;
224    reg = bridge->b_rrb_map[slot & 1].reg;
225
226    /* This needs to be done otherwise the rrb's on the virtual channel
227     * for this slot won't be freed !!
228     */
229    tmp = reg & 0xbbbbbbbb;
230
231    tmp ^= (0x11111111 * (7 - slot / 2));
232    tmp &= (0x33333333 & tmp) << 2;
233    tmp &= (0x44444444 & tmp) << 1;
234    while (less-- > 0) {
235	bit = LSBIT(tmp);
236	if (!bit) {
237	    rv = -1;
238	    break;
239	}
240	tmp &= ~bit;
241	reg &= ~bit;
242	clr |= bit;
243    }
244    bridge->b_rrb_map[slot & 1].reg = reg;
245
246    for (i = 0; i < 8; i++)
247	if (clr & (8 << (4 * i)))
248	    do_pcibr_rrb_clear(bridge, (2 * i) + (slot & 1));
249
250    return rv;
251}
252
253void
254do_pcibr_rrb_autoalloc(pcibr_soft_t pcibr_soft,
255		       int slot,
256		       int more_rrbs)
257{
258    bridge_t               *bridge = pcibr_soft->bs_base;
259    int                     got;
260
261    for (got = 0; got < more_rrbs; ++got) {
262	if (pcibr_soft->bs_rrb_res[slot & 7] > 0)
263	    pcibr_soft->bs_rrb_res[slot & 7]--;
264	else if (pcibr_soft->bs_rrb_avail[slot & 1] > 0)
265	    pcibr_soft->bs_rrb_avail[slot & 1]--;
266	else
267	    break;
268	if (do_pcibr_rrb_alloc(bridge, slot, 1) < 0)
269	    break;
270#if PCIBR_RRB_DEBUG
271	printk("do_pcibr_rrb_autoalloc: add one to slot %d%s\n",
272		slot & 7, slot & 8 ? "v" : "");
273#endif
274	pcibr_soft->bs_rrb_valid[slot]++;
275    }
276#if PCIBR_RRB_DEBUG
277    printk("%s: %d+%d free RRBs. Allocation list:\n", pcibr_soft->bs_name,
278	    pcibr_soft->bs_rrb_avail[0],
279	    pcibr_soft->bs_rrb_avail[1]);
280    for (slot = 0; slot < 8; ++slot)
281	printk("\t%d+%d+%d",
282		0xFFF & pcibr_soft->bs_rrb_valid[slot],
283		0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
284		pcibr_soft->bs_rrb_res[slot]);
285    printk("\n");
286#endif
287}
288
289/*
290 * Device driver interface to flush the write buffers for a specified
291 * device hanging off the bridge.
292 */
293int
294pcibr_wrb_flush(devfs_handle_t pconn_vhdl)
295{
296    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
297    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
298    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
299    bridge_t               *bridge = pcibr_soft->bs_base;
300    volatile bridgereg_t   *wrb_flush;
301
302    wrb_flush = &(bridge->b_wr_req_buf[pciio_slot].reg);
303    while (*wrb_flush);
304
305    return(0);
306}
307
308/*
309 * Device driver interface to request RRBs for a specified device
310 * hanging off a Bridge.  The driver requests the total number of
311 * RRBs it would like for the normal channel (vchan0) and for the
312 * "virtual channel" (vchan1).  The actual number allocated to each
313 * channel is returned.
314 *
315 * If we cannot allocate at least one RRB to a channel that needs
316 * at least one, return -1 (failure).  Otherwise, satisfy the request
317 * as best we can and return 0.
318 */
319int
320pcibr_rrb_alloc(devfs_handle_t pconn_vhdl,
321		int *count_vchan0,
322		int *count_vchan1)
323{
324    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
325    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
326    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
327    bridge_t               *bridge = pcibr_soft->bs_base;
328    int                     desired_vchan0;
329    int                     desired_vchan1;
330    int                     orig_vchan0;
331    int                     orig_vchan1;
332    int                     delta_vchan0;
333    int                     delta_vchan1;
334    int                     final_vchan0;
335    int                     final_vchan1;
336    int                     avail_rrbs;
337    int                     res_rrbs;
338    unsigned long           s;
339    int                     error;
340
341    /*
342     * TBD: temper request with admin info about RRB allocation,
343     * and according to demand from other devices on this Bridge.
344     *
345     * One way of doing this would be to allocate two RRBs
346     * for each device on the bus, before any drivers start
347     * asking for extras. This has the weakness that one
348     * driver might not give back an "extra" RRB until after
349     * another driver has already failed to get one that
350     * it wanted.
351     */
352
353    s = pcibr_lock(pcibr_soft);
354
355    /* Save the boot-time RRB configuration for this slot */
356    if (pcibr_soft->bs_rrb_valid_dflt[pciio_slot] < 0) {
357        pcibr_soft->bs_rrb_valid_dflt[pciio_slot] =
358                pcibr_soft->bs_rrb_valid[pciio_slot];
359        pcibr_soft->bs_rrb_valid_dflt[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL] =
360                pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
361        pcibr_soft->bs_rrb_res_dflt[pciio_slot] =
362                pcibr_soft->bs_rrb_res[pciio_slot];
363
364    }
365
366    /* How many RRBs do we own? */
367    orig_vchan0 = pcibr_soft->bs_rrb_valid[pciio_slot];
368    orig_vchan1 = pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
369
370    /* How many RRBs do we want? */
371    desired_vchan0 = count_vchan0 ? *count_vchan0 : orig_vchan0;
372    desired_vchan1 = count_vchan1 ? *count_vchan1 : orig_vchan1;
373
374    /* How many RRBs are free? */
375    avail_rrbs = pcibr_soft->bs_rrb_avail[pciio_slot & 1]
376	+ pcibr_soft->bs_rrb_res[pciio_slot];
377
378    /* Figure desired deltas */
379    delta_vchan0 = desired_vchan0 - orig_vchan0;
380    delta_vchan1 = desired_vchan1 - orig_vchan1;
381
382    /* Trim back deltas to something
383     * that we can actually meet, by
384     * decreasing the ending allocation
385     * for whichever channel wants
386     * more RRBs. If both want the same
387     * number, cut the second channel.
388     * NOTE: do not change the allocation for
389     * a channel that was passed as NULL.
390     */
391    while ((delta_vchan0 + delta_vchan1) > avail_rrbs) {
392	if (count_vchan0 &&
393	    (!count_vchan1 ||
394	     ((orig_vchan0 + delta_vchan0) >
395	      (orig_vchan1 + delta_vchan1))))
396	    delta_vchan0--;
397	else
398	    delta_vchan1--;
399    }
400
401    /* Figure final RRB allocations
402     */
403    final_vchan0 = orig_vchan0 + delta_vchan0;
404    final_vchan1 = orig_vchan1 + delta_vchan1;
405
406    /* If either channel wants RRBs but our actions
407     * would leave it with none, declare an error,
408     * but DO NOT change any RRB allocations.
409     */
410    if ((desired_vchan0 && !final_vchan0) ||
411	(desired_vchan1 && !final_vchan1)) {
412
413	error = -1;
414
415    } else {
416
417	/* Commit the allocations: free, then alloc.
418	 */
419	if (delta_vchan0 < 0)
420	    (void) do_pcibr_rrb_free(bridge, pciio_slot, -delta_vchan0);
421	if (delta_vchan1 < 0)
422	    (void) do_pcibr_rrb_free(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, -delta_vchan1);
423
424	if (delta_vchan0 > 0)
425	    (void) do_pcibr_rrb_alloc(bridge, pciio_slot, delta_vchan0);
426	if (delta_vchan1 > 0)
427	    (void) do_pcibr_rrb_alloc(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, delta_vchan1);
428
429	/* Return final values to caller.
430	 */
431	if (count_vchan0)
432	    *count_vchan0 = final_vchan0;
433	if (count_vchan1)
434	    *count_vchan1 = final_vchan1;
435
436	/* prevent automatic changes to this slot's RRBs
437	 */
438	pcibr_soft->bs_rrb_fixed |= 1 << pciio_slot;
439
440	/* Track the actual allocations, release
441	 * any further reservations, and update the
442	 * number of available RRBs.
443	 */
444
445	pcibr_soft->bs_rrb_valid[pciio_slot] = final_vchan0;
446	pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL] = final_vchan1;
447	pcibr_soft->bs_rrb_avail[pciio_slot & 1] =
448	    pcibr_soft->bs_rrb_avail[pciio_slot & 1]
449	    + pcibr_soft->bs_rrb_res[pciio_slot]
450	    - delta_vchan0
451	    - delta_vchan1;
452	pcibr_soft->bs_rrb_res[pciio_slot] = 0;
453
454        /*
455         * Reserve enough RRBs so this slot's RRB configuration can be
456         * reset to its boot-time default following a hot-plug shut-down
457         */
458        res_rrbs =   (pcibr_soft->bs_rrb_valid_dflt[pciio_slot] -
459                      pcibr_soft->bs_rrb_valid[pciio_slot])
460                   + (pcibr_soft->bs_rrb_valid_dflt[pciio_slot +
461                                                    PCIBR_RRB_SLOT_VIRTUAL] -
462                      pcibr_soft->bs_rrb_valid[pciio_slot +
463                                               PCIBR_RRB_SLOT_VIRTUAL])
464                   + (pcibr_soft->bs_rrb_res_dflt[pciio_slot] -
465                      pcibr_soft->bs_rrb_res[pciio_slot]);
466
467         if (res_rrbs > 0) {
468             pcibr_soft->bs_rrb_res[pciio_slot] = res_rrbs;
469             pcibr_soft->bs_rrb_avail[pciio_slot & 1] =
470                 pcibr_soft->bs_rrb_avail[pciio_slot & 1]
471                 - res_rrbs;
472         }
473
474#if PCIBR_RRB_DEBUG
475	printk("pcibr_rrb_alloc: slot %d set to %d+%d; %d+%d free\n",
476		pciio_slot, final_vchan0, final_vchan1,
477		pcibr_soft->bs_rrb_avail[0],
478		pcibr_soft->bs_rrb_avail[1]);
479	for (pciio_slot = 0; pciio_slot < 8; ++pciio_slot)
480	    printk("\t%d+%d+%d",
481		    0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot],
482		    0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL],
483		    pcibr_soft->bs_rrb_res[pciio_slot]);
484	printk("\n");
485#endif
486
487	error = 0;
488    }
489
490    pcibr_unlock(pcibr_soft, s);
491
492    return error;
493}
494
495/*
496 * Device driver interface to check the current state
497 * of the RRB allocations.
498 *
499 *   pconn_vhdl is your PCI connection point (specifies which
500 *      PCI bus and which slot).
501 *
502 *   count_vchan0 points to where to return the number of RRBs
503 *      assigned to the primary DMA channel, used by all DMA
504 *      that does not explicitly ask for the alternate virtual
505 *      channel.
506 *
507 *   count_vchan1 points to where to return the number of RRBs
508 *      assigned to the secondary DMA channel, used when
509 *      PCIBR_VCHAN1 and PCIIO_DMA_A64 are specified.
510 *
511 *   count_reserved points to where to return the number of RRBs
512 *      that have been automatically reserved for your device at
513 *      startup, but which have not been assigned to a
514 *      channel. RRBs must be assigned to a channel to be used;
515 *      this can be done either with an explicit pcibr_rrb_alloc
516 *      call, or automatically by the infrastructure when a DMA
517 *      translation is constructed. Any call to pcibr_rrb_alloc
518 *      will release any unassigned reserved RRBs back to the
519 *      free pool.
520 *
521 *   count_pool points to where to return the number of RRBs
522 *      that are currently unassigned and unreserved. This
523 *      number can (and will) change as other drivers make calls
524 *      to pcibr_rrb_alloc, or automatically allocate RRBs for
525 *      DMA beyond their initial reservation.
526 *
527 * NULL may be passed for any of the return value pointers
528 * the caller is not interested in.
529 *
530 * The return value is "0" if all went well, or "-1" if
531 * there is a problem. Additionally, if the wrong vertex
532 * is passed in, one of the subsidiary support functions
533 * could panic with a "bad pciio fingerprint."
534 */
535
536int
537pcibr_rrb_check(devfs_handle_t pconn_vhdl,
538		int *count_vchan0,
539		int *count_vchan1,
540		int *count_reserved,
541		int *count_pool)
542{
543    pciio_info_t            pciio_info;
544    pciio_slot_t            pciio_slot;
545    pcibr_soft_t            pcibr_soft;
546    unsigned long           s;
547    int                     error = -1;
548
549    if ((pciio_info = pciio_info_get(pconn_vhdl)) &&
550	(pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info)) &&
551	((pciio_slot = pciio_info_slot_get(pciio_info)) < 8)) {
552
553	s = pcibr_lock(pcibr_soft);
554
555	if (count_vchan0)
556	    *count_vchan0 =
557		pcibr_soft->bs_rrb_valid[pciio_slot];
558
559	if (count_vchan1)
560	    *count_vchan1 =
561		pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
562
563	if (count_reserved)
564	    *count_reserved =
565		pcibr_soft->bs_rrb_res[pciio_slot];
566
567	if (count_pool)
568	    *count_pool =
569		pcibr_soft->bs_rrb_avail[pciio_slot & 1];
570
571	error = 0;
572
573	pcibr_unlock(pcibr_soft, s);
574    }
575    return error;
576}
577
578/* pcibr_alloc_all_rrbs allocates all the rrbs available in the quantities
579 * requested for each of the devices.  The evn_odd argument indicates whether
580 * allocation is for the odd or even rrbs. The next group of four argument
581 * pairs indicate the amount of rrbs to be assigned to each device. The first
582 * argument of each pair indicate the total number of rrbs to allocate for that
583 * device. The second argument of each pair indicates how many rrb's from the
584 * first argument should be assigned to the virtual channel. The total of all
585 * of the first arguments should be <= 8. The second argument should be <= the
586 * first argument.
587 * if even_odd = 0 the devices in order are 0, 2, 4, 6
588 * if even_odd = 1 the devices in order are 1, 3, 5, 7
589 * returns 0 if no errors else returns -1
590 */
591
592int
593pcibr_alloc_all_rrbs(devfs_handle_t vhdl, int even_odd,
594		     int dev_1_rrbs, int virt1, int dev_2_rrbs, int virt2,
595		     int dev_3_rrbs, int virt3, int dev_4_rrbs, int virt4)
596{
597    devfs_handle_t          pcibr_vhdl;
598    pcibr_soft_t            pcibr_soft = (pcibr_soft_t)0;
599    bridge_t               *bridge = NULL;
600
601    uint32_t                rrb_setting = 0;
602    int                     rrb_shift = 7;
603    uint32_t                cur_rrb;
604    int                     dev_rrbs[4];
605    int                     virt[4];
606    int                     i, j;
607    unsigned long           s;
608
609    if (GRAPH_SUCCESS ==
610	hwgraph_traverse(vhdl, EDGE_LBL_PCI, &pcibr_vhdl)) {
611	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
612	if (pcibr_soft)
613	    bridge = pcibr_soft->bs_base;
614	hwgraph_vertex_unref(pcibr_vhdl);
615    }
616    if (bridge == NULL)
617	bridge = (bridge_t *) xtalk_piotrans_addr
618	    (vhdl, NULL, 0, sizeof(bridge_t), 0);
619
620    even_odd &= 1;
621
622    dev_rrbs[0] = dev_1_rrbs;
623    dev_rrbs[1] = dev_2_rrbs;
624    dev_rrbs[2] = dev_3_rrbs;
625    dev_rrbs[3] = dev_4_rrbs;
626
627    virt[0] = virt1;
628    virt[1] = virt2;
629    virt[2] = virt3;
630    virt[3] = virt4;
631
632    if ((dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs) > 8) {
633	return -1;
634    }
635    if ((dev_1_rrbs < 0) || (dev_2_rrbs < 0) || (dev_3_rrbs < 0) || (dev_4_rrbs < 0)) {
636	return -1;
637    }
638    /* walk through rrbs */
639    for (i = 0; i < 4; i++) {
640	if (virt[i]) {
641		for( j = 0; j < virt[i]; j++) {
642			cur_rrb = i | 0xc;
643			cur_rrb = cur_rrb << (rrb_shift * 4);
644			rrb_shift--;
645			rrb_setting = rrb_setting | cur_rrb;
646			dev_rrbs[i] = dev_rrbs[i] - 1;
647		}
648	}
649	for (j = 0; j < dev_rrbs[i]; j++) {
650	    cur_rrb = i | 0x8;
651	    cur_rrb = cur_rrb << (rrb_shift * 4);
652	    rrb_shift--;
653	    rrb_setting = rrb_setting | cur_rrb;
654	}
655    }
656
657    if (pcibr_soft)
658	s = pcibr_lock(pcibr_soft);
659
660    bridge->b_rrb_map[even_odd].reg = rrb_setting;
661
662    if (pcibr_soft) {
663
664	pcibr_soft->bs_rrb_fixed |= 0x55 << even_odd;
665
666	/* since we've "FIXED" the allocations
667	 * for these slots, we probably can dispense
668	 * with tracking avail/res/valid data, but
669	 * keeping it up to date helps debugging.
670	 */
671
672	pcibr_soft->bs_rrb_avail[even_odd] =
673	    8 - (dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs);
674
675	pcibr_soft->bs_rrb_res[even_odd + 0] = 0;
676	pcibr_soft->bs_rrb_res[even_odd + 2] = 0;
677	pcibr_soft->bs_rrb_res[even_odd + 4] = 0;
678	pcibr_soft->bs_rrb_res[even_odd + 6] = 0;
679
680	pcibr_soft->bs_rrb_valid[even_odd + 0] = dev_1_rrbs - virt1;
681	pcibr_soft->bs_rrb_valid[even_odd + 2] = dev_2_rrbs - virt2;
682	pcibr_soft->bs_rrb_valid[even_odd + 4] = dev_3_rrbs - virt3;
683	pcibr_soft->bs_rrb_valid[even_odd + 6] = dev_4_rrbs - virt4;
684
685	pcibr_soft->bs_rrb_valid[even_odd + 0 + PCIBR_RRB_SLOT_VIRTUAL] = virt1;
686	pcibr_soft->bs_rrb_valid[even_odd + 2 + PCIBR_RRB_SLOT_VIRTUAL] = virt2;
687	pcibr_soft->bs_rrb_valid[even_odd + 4 + PCIBR_RRB_SLOT_VIRTUAL] = virt3;
688	pcibr_soft->bs_rrb_valid[even_odd + 6 + PCIBR_RRB_SLOT_VIRTUAL] = virt4;
689
690	pcibr_unlock(pcibr_soft, s);
691    }
692    return 0;
693}
694
695/*
696 *    pcibr_rrb_flush: chase down all the RRBs assigned
697 *      to the specified connection point, and flush
698 *      them.
699 */
700void
701pcibr_rrb_flush(devfs_handle_t pconn_vhdl)
702{
703    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
704    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
705    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
706    bridge_t               *bridge = pcibr_soft->bs_base;
707    unsigned long           s;
708    reg_p                   rrbp;
709    unsigned                rrbm;
710    int                     i;
711    int                     rrbn;
712    unsigned                sval;
713    unsigned                mask;
714
715    sval = BRIDGE_RRB_EN | (pciio_slot >> 1);
716    mask = BRIDGE_RRB_EN | BRIDGE_RRB_PDEV;
717    rrbn = pciio_slot & 1;
718    rrbp = &bridge->b_rrb_map[rrbn].reg;
719
720    s = pcibr_lock(pcibr_soft);
721    rrbm = *rrbp;
722    for (i = 0; i < 8; ++i) {
723	if ((rrbm & mask) == sval)
724	    do_pcibr_rrb_flush(bridge, rrbn);
725	rrbm >>= 4;
726	rrbn += 2;
727    }
728    pcibr_unlock(pcibr_soft, s);
729}
730
731/*
732 * pcibr_slot_initial_rrb_alloc
733 *	Allocate a default number of rrbs for this slot on
734 * 	the two channels.  This is dictated by the rrb allocation
735 * 	strategy routine defined per platform.
736 */
737
738int
739pcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl,
740			     pciio_slot_t slot)
741{
742    pcibr_soft_t	 pcibr_soft;
743    pcibr_info_h	 pcibr_infoh;
744    pcibr_info_t	 pcibr_info;
745    bridge_t		*bridge;
746    int                  c0, c1, r;
747
748    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
749
750    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
751	return(EINVAL);
752
753    bridge = pcibr_soft->bs_base;
754
755    /* How may RRBs are on this slot?
756     */
757    c0 = do_pcibr_rrb_count_valid(bridge, slot);
758    c1 = do_pcibr_rrb_count_valid(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL);
759
760#if PCIBR_RRB_DEBUG
761    printk(
762	    "pcibr_slot_initial_rrb_alloc: slot %d started with %d+%d\n",
763            slot, c0, c1);
764#endif
765
766    /* Do we really need any?
767     */
768    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
769    pcibr_info = pcibr_infoh[0];
770    if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) &&
771	!pcibr_soft->bs_slot[slot].has_host) {
772	if (c0 > 0)
773	    do_pcibr_rrb_free(bridge, slot, c0);
774	if (c1 > 0)
775	    do_pcibr_rrb_free(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL, c1);
776	pcibr_soft->bs_rrb_valid[slot] = 0x1000;
777	pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0x1000;
778	return(ENODEV);
779    }
780
781    pcibr_soft->bs_rrb_avail[slot & 1] -= c0 + c1;
782    pcibr_soft->bs_rrb_valid[slot] = c0;
783    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = c1;
784
785    pcibr_soft->bs_rrb_avail[0] = do_pcibr_rrb_count_avail(bridge, 0);
786    pcibr_soft->bs_rrb_avail[1] = do_pcibr_rrb_count_avail(bridge, 1);
787
788    r = 3 - (c0 + c1);
789
790    if (r > 0) {
791	pcibr_soft->bs_rrb_res[slot] = r;
792	pcibr_soft->bs_rrb_avail[slot & 1] -= r;
793    }
794
795#if PCIBR_RRB_DEBUG
796    printk("\t%d+%d+%d",
797	    0xFFF & pcibr_soft->bs_rrb_valid[slot],
798	    0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
799	    pcibr_soft->bs_rrb_res[slot]);
800    printk("\n");
801#endif
802
803    return(0);
804}
805
806/*
807 * pcibr_initial_rrb
808 *      Assign an equal total number of RRBs to all candidate slots,
809 *      where the total is the sum of the number of RRBs assigned to
810 *      the normal channel, the number of RRBs assigned to the virtual
811 *      channel, and the number of RRBs assigned as reserved.
812 *
813 *      A candidate slot is a populated slot on a non-SN1 system or
814 *      any existing (populated or empty) slot on an SN1 system.
815 *      Empty SN1 slots need RRBs to support hot-plug operations.
816 */
817
818int
819pcibr_initial_rrb(devfs_handle_t pcibr_vhdl,
820			     pciio_slot_t first, pciio_slot_t last)
821{
822    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
823    bridge_t               *bridge = pcibr_soft->bs_base;
824    pciio_slot_t            slot;
825    int                     c0, c1;
826    int                     have[2][3];
827    int                     res[2];
828    int                     eo;
829
830    have[0][0] = have[0][1] = have[0][2] = 0;
831    have[1][0] = have[1][1] = have[1][2] = 0;
832    res[0] = res[1] = 0;
833
834    for (slot = 0; slot < 8; ++slot) {
835        /* Initial RRB management; give back RRBs in all non-existent slots */
836        (void) pcibr_slot_initial_rrb_alloc(pcibr_vhdl, slot);
837
838        /* Base calculations only on existing slots */
839        if ((slot >= first) && (slot <= last)) {
840            c0 = pcibr_soft->bs_rrb_valid[slot];
841            c1 = pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL];
842            if ((c0 + c1) < 3)
843                have[slot & 1][c0 + c1]++;
844        }
845    }
846
847    /* Initialize even/odd slot available RRB counts */
848    pcibr_soft->bs_rrb_avail[0] = do_pcibr_rrb_count_avail(bridge, 0);
849    pcibr_soft->bs_rrb_avail[1] = do_pcibr_rrb_count_avail(bridge, 1);
850
851    /*
852     * Calculate reserved RRBs for slots based on current RRB usage
853     */
854    for (eo = 0; eo < 2; eo++) {
855        if ((3 * have[eo][0] + 2 * have[eo][1] + have[eo][2]) <= pcibr_soft->bs_rrb_avail[eo])
856            res[eo] = 3;
857        else if ((2 * have[eo][0] + have[eo][1]) <= pcibr_soft->bs_rrb_avail[eo])
858            res[eo] = 2;
859        else if (have[eo][0] <= pcibr_soft->bs_rrb_avail[eo])
860            res[eo] = 1;
861        else
862            res[eo] = 0;
863
864    }
865
866    /* Assign reserved RRBs to existing slots */
867    for (slot = first; slot <= last; ++slot) {
868        int                     r;
869
870        c0 = pcibr_soft->bs_rrb_valid[slot];
871        c1 = pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL];
872        r = res[slot & 1] - (c0 + c1);
873
874        if (r > 0) {
875            pcibr_soft->bs_rrb_res[slot] = r;
876            pcibr_soft->bs_rrb_avail[slot & 1] -= r;
877            }
878    }
879
880#if PCIBR_RRB_DEBUG
881    printk("%v RRB MANAGEMENT: %d+%d free\n",
882            pcibr_vhdl,
883            pcibr_soft->bs_rrb_avail[0],
884            pcibr_soft->bs_rrb_avail[1]);
885    for (slot = first; slot <= last; ++slot)
886        printk("\tslot %d: %d+%d+%d", slot,
887                0xFFF & pcibr_soft->bs_rrb_valid[slot],
888                0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
889                pcibr_soft->bs_rrb_res[slot]);
890    printk("\n");
891#endif
892
893    return 0;
894
895}
896
897