more changes on original files
[linux-2.4.git] / arch / ia64 / sn / io / sn2 / pcibr / pcibr_rrb.c
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-2003 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/io.h>
31 #include <asm/sn/sn_private.h>
32
33 void              do_pcibr_rrb_clear(bridge_t *, int);
34 void              do_pcibr_rrb_flush(bridge_t *, int);
35 int               do_pcibr_rrb_count_valid(bridge_t *, pciio_slot_t, int);
36 int               do_pcibr_rrb_count_avail(bridge_t *, pciio_slot_t);
37 int               do_pcibr_rrb_alloc(bridge_t *, pciio_slot_t, int, int);
38 int               do_pcibr_rrb_free(bridge_t *, pciio_slot_t, int, int);
39 void              do_pcibr_rrb_free_all(pcibr_soft_t, bridge_t *, pciio_slot_t);
40
41 void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int, int);
42
43 int               pcibr_wrb_flush(vertex_hdl_t);
44 int               pcibr_rrb_alloc(vertex_hdl_t, int *, int *);
45 int               pcibr_rrb_check(vertex_hdl_t, int *, int *, int *, int *);
46 void              pcibr_rrb_flush(vertex_hdl_t);
47 int               pcibr_slot_initial_rrb_alloc(vertex_hdl_t,pciio_slot_t);
48
49 void              pcibr_rrb_debug(char *, pcibr_soft_t);
50
51 /*
52  * RRB Management
53  *
54  * All the do_pcibr_rrb_ routines manipulate the Read Response Buffer (rrb)
55  * registers within the Bridge.  Two 32 registers (b_rrb_map[2] also known
56  * as the b_even_resp & b_odd_resp registers) are used to allocate the 16
57  * rrbs to devices.  The b_even_resp register represents even num devices,
58  * and b_odd_resp represent odd number devices.  Each rrb is represented by
59  * 4-bits within a register.
60  *   BRIDGE & XBRIDGE:  1 enable bit, 1 virtual channel bit, 2 device bits
61  *   PIC:               1 enable bit, 2 virtual channel bits, 1 device bit
62  * PIC has 4 devices per bus, and 4 virtual channels (1 normal & 3 virtual)
63  * per device.  BRIDGE & XBRIDGE have 8 devices per bus and 2 virtual
64  * channels (1 normal & 1 virtual) per device.  See the BRIDGE and PIC ASIC
65  * Programmers Reference guides for more information.
66  */ 
67  
68 #define RRB_MASK (0xf)                  /* mask a single rrb within reg */
69 #define RRB_SIZE (4)                    /* sizeof rrb within reg (bits) */
70  
71 #define RRB_ENABLE_BIT(bridge)          (0x8)  /* [BRIDGE | PIC]_RRB_EN */
72 #define NUM_PDEV_BITS(bridge)           (1)
73 #define NUM_VDEV_BITS(bridge)           (2)
74 #define NUMBER_VCHANNELS(bridge)        (4)
75 #define SLOT_2_PDEV(bridge, slot)       ((slot) >> 1)
76 #define SLOT_2_RRB_REG(bridge, slot)    ((slot) & 0x1)
77  
78 /* validate that the slot and virtual channel are valid for a given bridge */
79 #define VALIDATE_SLOT_n_VCHAN(bridge, s, v) \
80     (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)3)) && (((v) >= 0) && ((v) <= 3))) ? 1 : 0)
81  
82 /*  
83  * Count how many RRBs are marked valid for the specified PCI slot
84  * and virtual channel.  Return the count.
85  */ 
86 int
87 do_pcibr_rrb_count_valid(bridge_t *bridge,
88                          pciio_slot_t slot,
89                          int vchan)
90 {
91     bridgereg_t tmp;
92     uint16_t enable_bit, vchan_bits, pdev_bits, rrb_bits;
93     int rrb_index, cnt=0;
94
95     if (!VALIDATE_SLOT_n_VCHAN(bridge, slot, vchan)) {
96         printk(KERN_WARNING "do_pcibr_rrb_count_valid() invalid slot/vchan [%d/%d]\n", slot, vchan);
97         return 0;
98     }
99     
100     enable_bit = RRB_ENABLE_BIT(bridge);
101     vchan_bits = vchan << NUM_PDEV_BITS(bridge);
102     pdev_bits = SLOT_2_PDEV(bridge, slot);
103     rrb_bits = enable_bit | vchan_bits | pdev_bits;
104     
105     tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
106
107     for (rrb_index = 0; rrb_index < 8; rrb_index++) {
108         if ((tmp & RRB_MASK) == rrb_bits)
109             cnt++;
110         tmp = (tmp >> RRB_SIZE);
111     }
112     return cnt;
113 }
114  
115  
116 /*  
117  * Count how many RRBs are available to be allocated to the specified
118  * slot.  Return the count.
119  */ 
120 int
121 do_pcibr_rrb_count_avail(bridge_t *bridge,
122                          pciio_slot_t slot)
123 {
124     bridgereg_t tmp;
125     uint16_t enable_bit;
126     int rrb_index, cnt=0;
127     
128     if (!VALIDATE_SLOT_n_VCHAN(bridge, slot, 0)) {
129         printk(KERN_WARNING "do_pcibr_rrb_count_avail() invalid slot/vchan");
130         return 0;
131     }
132     
133     enable_bit = RRB_ENABLE_BIT(bridge);
134
135     tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
136
137     for (rrb_index = 0; rrb_index < 8; rrb_index++) {
138         if ((tmp & enable_bit) != enable_bit)
139             cnt++;
140         tmp = (tmp >> RRB_SIZE);
141     }
142     return cnt;
143 }
144  
145  
146 /*  
147  * Allocate some additional RRBs for the specified slot and the specified
148  * virtual channel.  Returns -1 if there were insufficient free RRBs to
149  * satisfy the request, or 0 if the request was fulfilled.
150  *
151  * Note that if a request can be partially filled, it will be, even if
152  * we return failure.
153  */ 
154 int
155 do_pcibr_rrb_alloc(bridge_t *bridge,
156                    pciio_slot_t slot,
157                    int vchan,
158                    int more)
159 {
160     bridgereg_t reg, tmp = (bridgereg_t)0;
161     uint16_t enable_bit, vchan_bits, pdev_bits, rrb_bits;
162     int rrb_index;
163     
164     if (!VALIDATE_SLOT_n_VCHAN(bridge, slot, vchan)) {
165         printk(KERN_WARNING "do_pcibr_rrb_alloc() invalid slot/vchan");
166         return -1;
167     }
168     
169     enable_bit = RRB_ENABLE_BIT(bridge);
170     vchan_bits = vchan << NUM_PDEV_BITS(bridge);
171     pdev_bits = SLOT_2_PDEV(bridge, slot);
172     rrb_bits = enable_bit | vchan_bits | pdev_bits;
173
174     reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
175
176     for (rrb_index = 0; ((rrb_index < 8) && (more > 0)); rrb_index++) {
177         if ((tmp & enable_bit) != enable_bit) {
178             /* clear the rrb and OR in the new rrb into 'reg' */
179             reg = reg & ~(RRB_MASK << (RRB_SIZE * rrb_index));
180             reg = reg | (rrb_bits << (RRB_SIZE * rrb_index));
181             more--;
182         }
183         tmp = (tmp >> RRB_SIZE);
184     }
185
186     bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
187     return (more ? -1 : 0);
188 }
189  
190  
191 /*  
192  * Release some of the RRBs that have been allocated for the specified
193  * slot. Returns zero for success, or negative if it was unable to free
194  * that many RRBs.
195  *
196  * Note that if a request can be partially fulfilled, it will be, even
197  * if we return failure.
198  */ 
199 int
200 do_pcibr_rrb_free(bridge_t *bridge,
201                   pciio_slot_t slot,
202                   int vchan,
203                   int less)
204 {
205     bridgereg_t reg, tmp = (bridgereg_t)0, clr = 0;
206     uint16_t enable_bit, vchan_bits, pdev_bits, rrb_bits;
207     int rrb_index;
208     
209     if (!VALIDATE_SLOT_n_VCHAN(bridge, slot, vchan)) {
210         printk(KERN_WARNING "do_pcibr_rrb_free() invalid slot/vchan");
211         return -1;
212     }
213     
214     enable_bit = RRB_ENABLE_BIT(bridge);
215     vchan_bits = vchan << NUM_PDEV_BITS(bridge);
216     pdev_bits = SLOT_2_PDEV(bridge, slot);
217     rrb_bits = enable_bit | vchan_bits | pdev_bits;
218
219     reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
220
221     for (rrb_index = 0; ((rrb_index < 8) && (less > 0)); rrb_index++) {
222         if ((tmp & RRB_MASK) == rrb_bits) {
223            /*
224             * the old do_pcibr_rrb_free() code only clears the enable bit
225             * but I say we should clear the whole rrb (ie):
226             *     reg = reg & ~(RRB_MASK << (RRB_SIZE * rrb_index));
227             * But to be compatible with old code we'll only clear enable.
228             */
229             reg = reg & ~(RRB_ENABLE_BIT(bridge) << (RRB_SIZE * rrb_index));
230             clr = clr | (enable_bit << (RRB_SIZE * rrb_index));
231             less--;
232         }
233         tmp = (tmp >> RRB_SIZE);
234     }
235
236     bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
237
238     /* call do_pcibr_rrb_clear() for all the rrbs we've freed */
239     for (rrb_index = 0; rrb_index < 8; rrb_index++) {
240         int evn_odd = SLOT_2_RRB_REG(bridge, slot);
241         if (clr & (enable_bit << (RRB_SIZE * rrb_index)))
242             do_pcibr_rrb_clear(bridge, (2 * rrb_index) + evn_odd);
243     }
244     
245     return (less ? -1 : 0);
246 }
247  
248   
249 /*  
250  * free all the rrbs (both the normal and virtual channels) for the
251  * specified slot.
252  */ 
253 void
254 do_pcibr_rrb_free_all(pcibr_soft_t pcibr_soft,
255                       bridge_t *bridge,
256                       pciio_slot_t slot)
257 {
258     int vchan;
259     int vchan_total = NUMBER_VCHANNELS(bridge);
260     
261     /* pretend we own all 8 rrbs and just ignore the return value */
262     for (vchan = 0; vchan < vchan_total; vchan++) {
263             (void)do_pcibr_rrb_free(bridge, slot, vchan, 8);
264             pcibr_soft->bs_rrb_valid[slot][vchan] = 0;
265     }
266 }
267  
268  
269 /*
270  * Wait for the the specified rrb to have no outstanding XIO pkts
271  * and for all data to be drained.  Mark the rrb as no longer being 
272  * valid.
273  */
274 void
275 do_pcibr_rrb_clear(bridge_t *bridge, int rrb)
276 {
277     bridgereg_t             status;
278
279     /* bridge_lock must be held;
280      * this RRB must be disabled.
281      */
282
283     /* wait until RRB has no outstanduing XIO packets. */
284     while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
285         ;                               /* XXX- beats on bridge. bad idea? */
286     }
287
288     /* if the RRB has data, drain it. */
289     if (status & BRIDGE_RRB_VALID(rrb)) {
290         bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
291
292         /* wait until RRB is no longer valid. */
293         while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
294                 ;                               /* XXX- beats on bridge. bad idea? */
295         }
296     }
297 }
298
299
300 /* 
301  * Flush the specified rrb by calling do_pcibr_rrb_clear().  This
302  * routine is just a wrapper to make sure the rrb is disabled 
303  * before calling do_pcibr_rrb_clear().
304  */
305 void
306 do_pcibr_rrb_flush(bridge_t *bridge, int rrbn)
307 {
308     reg_p        rrbp = &bridge->b_rrb_map[rrbn & 1].reg;
309     bridgereg_t  rrbv;
310     int          shft = (RRB_SIZE * (rrbn >> 1));
311     unsigned long        ebit = RRB_ENABLE_BIT(bridge) << shft;
312
313     rrbv = *rrbp;
314
315     if (rrbv & ebit) {
316         *rrbp = rrbv & ~ebit;
317     }
318
319     do_pcibr_rrb_clear(bridge, rrbn);
320
321     if (rrbv & ebit) {
322         *rrbp = rrbv;
323     }
324 }
325
326
327 void
328 do_pcibr_rrb_autoalloc(pcibr_soft_t pcibr_soft,
329                        int slot,
330                        int vchan, 
331                        int more_rrbs)
332 {
333     bridge_t               *bridge = pcibr_soft->bs_base;
334     int                     got;
335
336     for (got = 0; got < more_rrbs; ++got) {
337         if (pcibr_soft->bs_rrb_res[slot] > 0)
338             pcibr_soft->bs_rrb_res[slot]--;
339         else if (pcibr_soft->bs_rrb_avail[slot & 1] > 0)
340             pcibr_soft->bs_rrb_avail[slot & 1]--;
341         else
342             break;
343         if (do_pcibr_rrb_alloc(bridge, slot, vchan, 1) < 0)
344             break;
345
346         pcibr_soft->bs_rrb_valid[slot][vchan]++;
347     }
348
349     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_soft->bs_vhdl,
350                 "do_pcibr_rrb_autoalloc: added %d (of %d requested) RRBs "
351                 "to slot %d, vchan %d\n", got, more_rrbs, 
352                 PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), vchan));
353
354     pcibr_rrb_debug("do_pcibr_rrb_autoalloc", pcibr_soft);
355 }
356
357
358 /*
359  * Flush all the rrb's assigned to the specified connection point.
360  */
361 void
362 pcibr_rrb_flush(vertex_hdl_t pconn_vhdl)
363 {
364     pciio_info_t  pciio_info = pciio_info_get(pconn_vhdl);
365     pcibr_soft_t  pcibr_soft = (pcibr_soft_t)pciio_info_mfast_get(pciio_info);
366     pciio_slot_t  slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
367     bridge_t     *bridge = pcibr_soft->bs_base;
368
369     bridgereg_t tmp;
370     uint16_t enable_bit, pdev_bits, rrb_bits, rrb_mask;
371     int rrb_index;
372     unsigned long s;
373
374     enable_bit = RRB_ENABLE_BIT(bridge);
375     pdev_bits = SLOT_2_PDEV(bridge, slot);
376     rrb_bits = enable_bit | pdev_bits;
377     rrb_mask = enable_bit | ((NUM_PDEV_BITS(bridge) << 1) - 1);
378
379     tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
380
381     s = pcibr_lock(pcibr_soft);
382     for (rrb_index = 0; rrb_index < 8; rrb_index++) {
383         int evn_odd = SLOT_2_RRB_REG(bridge, slot);
384         if ((tmp & rrb_mask) == rrb_bits)
385             do_pcibr_rrb_flush(bridge, (2 * rrb_index) + evn_odd);
386         tmp = (tmp >> RRB_SIZE);
387     }
388     pcibr_unlock(pcibr_soft, s);
389 }
390
391
392 /*
393  * Device driver interface to flush the write buffers for a specified
394  * device hanging off the bridge.
395  */
396 int
397 pcibr_wrb_flush(vertex_hdl_t pconn_vhdl)
398 {
399     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
400     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
401     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
402     bridge_t               *bridge = pcibr_soft->bs_base;
403     volatile bridgereg_t   *wrb_flush;
404
405     wrb_flush = &(bridge->b_wr_req_buf[pciio_slot].reg);
406     if ( IS_PIC_SOFT(pcibr_soft) ) {
407         while (*wrb_flush)
408                 ;
409     }
410     return(0);
411 }
412
413 /*
414  * Device driver interface to request RRBs for a specified device
415  * hanging off a Bridge.  The driver requests the total number of
416  * RRBs it would like for the normal channel (vchan0) and for the
417  * "virtual channel" (vchan1).  The actual number allocated to each
418  * channel is returned.
419  *
420  * If we cannot allocate at least one RRB to a channel that needs
421  * at least one, return -1 (failure).  Otherwise, satisfy the request
422  * as best we can and return 0.
423  */
424 int
425 pcibr_rrb_alloc(vertex_hdl_t pconn_vhdl,
426                 int *count_vchan0,
427                 int *count_vchan1)
428 {
429     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
430     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
431     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
432     bridge_t               *bridge = pcibr_soft->bs_base;
433     int                     desired_vchan0;
434     int                     desired_vchan1;
435     int                     orig_vchan0;
436     int                     orig_vchan1;
437     int                     delta_vchan0;
438     int                     delta_vchan1;
439     int                     final_vchan0;
440     int                     final_vchan1;
441     int                     avail_rrbs;
442     int                     res_rrbs;
443     int                     vchan_total;
444     int                     vchan;
445     unsigned long                s;
446     int                     error;
447
448     /*
449      * TBD: temper request with admin info about RRB allocation,
450      * and according to demand from other devices on this Bridge.
451      *
452      * One way of doing this would be to allocate two RRBs
453      * for each device on the bus, before any drivers start
454      * asking for extras. This has the weakness that one
455      * driver might not give back an "extra" RRB until after
456      * another driver has already failed to get one that
457      * it wanted.
458      */
459
460     s = pcibr_lock(pcibr_soft);
461
462     vchan_total = NUMBER_VCHANNELS(bridge);
463
464     /* Save the boot-time RRB configuration for this slot */
465     if (pcibr_soft->bs_rrb_valid_dflt[pciio_slot][VCHAN0] < 0) {
466         for (vchan = 0; vchan < vchan_total; vchan++) 
467             pcibr_soft->bs_rrb_valid_dflt[pciio_slot][vchan] =
468                     pcibr_soft->bs_rrb_valid[pciio_slot][vchan];
469         pcibr_soft->bs_rrb_res_dflt[pciio_slot] =
470                 pcibr_soft->bs_rrb_res[pciio_slot];
471                   
472     }
473
474     /* How many RRBs do we own? */
475     orig_vchan0 = pcibr_soft->bs_rrb_valid[pciio_slot][VCHAN0];
476     orig_vchan1 = pcibr_soft->bs_rrb_valid[pciio_slot][VCHAN1];
477
478     /* How many RRBs do we want? */
479     desired_vchan0 = count_vchan0 ? *count_vchan0 : orig_vchan0;
480     desired_vchan1 = count_vchan1 ? *count_vchan1 : orig_vchan1;
481
482     /* How many RRBs are free? */
483     avail_rrbs = pcibr_soft->bs_rrb_avail[pciio_slot & 1]
484         + pcibr_soft->bs_rrb_res[pciio_slot];
485
486     /* Figure desired deltas */
487     delta_vchan0 = desired_vchan0 - orig_vchan0;
488     delta_vchan1 = desired_vchan1 - orig_vchan1;
489
490     /* Trim back deltas to something
491      * that we can actually meet, by
492      * decreasing the ending allocation
493      * for whichever channel wants
494      * more RRBs. If both want the same
495      * number, cut the second channel.
496      * NOTE: do not change the allocation for
497      * a channel that was passed as NULL.
498      */
499     while ((delta_vchan0 + delta_vchan1) > avail_rrbs) {
500         if (count_vchan0 &&
501             (!count_vchan1 ||
502              ((orig_vchan0 + delta_vchan0) >
503               (orig_vchan1 + delta_vchan1))))
504             delta_vchan0--;
505         else
506             delta_vchan1--;
507     }
508
509     /* Figure final RRB allocations
510      */
511     final_vchan0 = orig_vchan0 + delta_vchan0;
512     final_vchan1 = orig_vchan1 + delta_vchan1;
513
514     /* If either channel wants RRBs but our actions
515      * would leave it with none, declare an error,
516      * but DO NOT change any RRB allocations.
517      */
518     if ((desired_vchan0 && !final_vchan0) ||
519         (desired_vchan1 && !final_vchan1)) {
520
521         error = -1;
522
523     } else {
524
525         /* Commit the allocations: free, then alloc.
526          */
527         if (delta_vchan0 < 0)
528             (void) do_pcibr_rrb_free(bridge, pciio_slot, VCHAN0, -delta_vchan0);
529         if (delta_vchan1 < 0)
530             (void) do_pcibr_rrb_free(bridge, pciio_slot, VCHAN1, -delta_vchan1);
531
532         if (delta_vchan0 > 0)
533             (void) do_pcibr_rrb_alloc(bridge, pciio_slot, VCHAN0, delta_vchan0);
534         if (delta_vchan1 > 0)
535             (void) do_pcibr_rrb_alloc(bridge, pciio_slot, VCHAN1, delta_vchan1);
536
537         /* Return final values to caller.
538          */
539         if (count_vchan0)
540             *count_vchan0 = final_vchan0;
541         if (count_vchan1)
542             *count_vchan1 = final_vchan1;
543
544         /* prevent automatic changes to this slot's RRBs
545          */
546         pcibr_soft->bs_rrb_fixed |= 1 << pciio_slot;
547
548         /* Track the actual allocations, release
549          * any further reservations, and update the
550          * number of available RRBs.
551          */
552
553         pcibr_soft->bs_rrb_valid[pciio_slot][VCHAN0] = final_vchan0;
554         pcibr_soft->bs_rrb_valid[pciio_slot][VCHAN1] = final_vchan1;
555         pcibr_soft->bs_rrb_avail[pciio_slot & 1] =
556             pcibr_soft->bs_rrb_avail[pciio_slot & 1]
557             + pcibr_soft->bs_rrb_res[pciio_slot]
558             - delta_vchan0
559             - delta_vchan1;
560         pcibr_soft->bs_rrb_res[pciio_slot] = 0;
561
562         /*
563          * Reserve enough RRBs so this slot's RRB configuration can be
564          * reset to its boot-time default following a hot-plug shut-down
565          */
566         res_rrbs = (pcibr_soft->bs_rrb_res_dflt[pciio_slot] -
567                     pcibr_soft->bs_rrb_res[pciio_slot]);
568         for (vchan = 0; vchan < vchan_total; vchan++) {
569             res_rrbs += (pcibr_soft->bs_rrb_valid_dflt[pciio_slot][vchan] -
570                          pcibr_soft->bs_rrb_valid[pciio_slot][vchan]);
571         }
572
573         if (res_rrbs > 0) {
574             pcibr_soft->bs_rrb_res[pciio_slot] = res_rrbs;
575             pcibr_soft->bs_rrb_avail[pciio_slot & 1] =
576                 pcibr_soft->bs_rrb_avail[pciio_slot & 1]
577                 - res_rrbs;
578         }
579  
580         pcibr_rrb_debug("pcibr_rrb_alloc", pcibr_soft);
581
582         error = 0;
583     }
584
585     pcibr_unlock(pcibr_soft, s);
586
587     return error;
588 }
589
590 /*
591  * Device driver interface to check the current state
592  * of the RRB allocations.
593  *
594  *   pconn_vhdl is your PCI connection point (specifies which
595  *      PCI bus and which slot).
596  *
597  *   count_vchan0 points to where to return the number of RRBs
598  *      assigned to the primary DMA channel, used by all DMA
599  *      that does not explicitly ask for the alternate virtual
600  *      channel.
601  *
602  *   count_vchan1 points to where to return the number of RRBs
603  *      assigned to the secondary DMA channel, used when
604  *      PCIBR_VCHAN1 and PCIIO_DMA_A64 are specified.
605  *
606  *   count_reserved points to where to return the number of RRBs
607  *      that have been automatically reserved for your device at
608  *      startup, but which have not been assigned to a
609  *      channel. RRBs must be assigned to a channel to be used;
610  *      this can be done either with an explicit pcibr_rrb_alloc
611  *      call, or automatically by the infrastructure when a DMA
612  *      translation is constructed. Any call to pcibr_rrb_alloc
613  *      will release any unassigned reserved RRBs back to the
614  *      free pool.
615  *
616  *   count_pool points to where to return the number of RRBs
617  *      that are currently unassigned and unreserved. This
618  *      number can (and will) change as other drivers make calls
619  *      to pcibr_rrb_alloc, or automatically allocate RRBs for
620  *      DMA beyond their initial reservation.
621  *
622  * NULL may be passed for any of the return value pointers
623  * the caller is not interested in.
624  *
625  * The return value is "0" if all went well, or "-1" if
626  * there is a problem. Additionally, if the wrong vertex
627  * is passed in, one of the subsidiary support functions
628  * could panic with a "bad pciio fingerprint."
629  */
630
631 int
632 pcibr_rrb_check(vertex_hdl_t pconn_vhdl,
633                 int *count_vchan0,
634                 int *count_vchan1,
635                 int *count_reserved,
636                 int *count_pool)
637 {
638     pciio_info_t            pciio_info;
639     pciio_slot_t            pciio_slot;
640     pcibr_soft_t            pcibr_soft;
641     unsigned long                s;
642     int                     error = -1;
643
644     if ((pciio_info = pciio_info_get(pconn_vhdl)) &&
645         (pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info)) &&
646         ((pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info)) < PCIBR_NUM_SLOTS(pcibr_soft))) {
647
648         s = pcibr_lock(pcibr_soft);
649
650         if (count_vchan0)
651             *count_vchan0 =
652                 pcibr_soft->bs_rrb_valid[pciio_slot][VCHAN0];
653
654         if (count_vchan1)
655             *count_vchan1 =
656                 pcibr_soft->bs_rrb_valid[pciio_slot][VCHAN1];
657
658         if (count_reserved)
659             *count_reserved =
660                 pcibr_soft->bs_rrb_res[pciio_slot];
661
662         if (count_pool)
663             *count_pool =
664                 pcibr_soft->bs_rrb_avail[pciio_slot & 1];
665
666         error = 0;
667
668         pcibr_unlock(pcibr_soft, s);
669     }
670     return error;
671 }
672
673 /*
674  * pcibr_slot_initial_rrb_alloc
675  *      Allocate a default number of rrbs for this slot on 
676  *      the two channels.  This is dictated by the rrb allocation
677  *      strategy routine defined per platform.
678  */
679
680 int
681 pcibr_slot_initial_rrb_alloc(vertex_hdl_t pcibr_vhdl,
682                              pciio_slot_t slot)
683 {
684     pcibr_soft_t         pcibr_soft;
685     pcibr_info_h         pcibr_infoh;
686     pcibr_info_t         pcibr_info;
687     bridge_t            *bridge;
688     int                  vchan_total;
689     int                  vchan;
690     int                  chan[4];
691
692     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
693
694     if (!pcibr_soft)
695         return(-EINVAL);
696
697     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
698         return(-EINVAL);
699
700     bridge = pcibr_soft->bs_base;
701
702     /* How many RRBs are on this slot? */
703     vchan_total = NUMBER_VCHANNELS(bridge);
704     for (vchan = 0; vchan < vchan_total; vchan++) 
705         chan[vchan] = do_pcibr_rrb_count_valid(bridge, slot, vchan);
706
707     if (IS_PIC_SOFT(pcibr_soft)) {
708         PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_vhdl,
709             "pcibr_slot_initial_rrb_alloc: slot %d started with %d+%d+%d+%d\n",
710             PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), 
711             chan[VCHAN0], chan[VCHAN1], chan[VCHAN2], chan[VCHAN3]));
712     } else {
713         PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_vhdl,
714             "pcibr_slot_initial_rrb_alloc: slot %d started with %d+%d\n",
715             PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), 
716             chan[VCHAN0], chan[VCHAN1]));
717     }
718
719     /* Do we really need any?
720      */
721     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
722     pcibr_info = pcibr_infoh[0];
723
724     if (PCIBR_WAR_ENABLED(PV856866, pcibr_soft) && IS_PIC_SOFT(pcibr_soft) &&
725                         (slot == 2 || slot == 3) &&
726                         (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) &&
727                         !pcibr_soft->bs_slot[slot].has_host) {
728
729         for (vchan = 0; vchan < 2; vchan++) {
730             do_pcibr_rrb_free(bridge, slot, vchan, 8);
731             pcibr_soft->bs_rrb_valid[slot][vchan] = 0;
732         }
733
734         pcibr_soft->bs_rrb_valid[slot][3] = chan[3];
735
736         return(-ENODEV);
737     }
738
739     /* Give back any assigned to empty slots */
740     if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) && !pcibr_soft->bs_slot[slot].has_host) {
741         do_pcibr_rrb_free_all(pcibr_soft, bridge, slot);
742         return(-ENODEV);
743     }
744
745     for (vchan = 0; vchan < vchan_total; vchan++)
746         pcibr_soft->bs_rrb_valid[slot][vchan] = chan[vchan];
747
748     return(0);
749 }
750
751 void
752 rrb_reserved_free(pcibr_soft_t pcibr_soft, int slot)
753 {
754         int res = pcibr_soft->bs_rrb_res[slot];
755
756         if (res) {
757                  pcibr_soft->bs_rrb_avail[slot & 1] += res;
758                  pcibr_soft->bs_rrb_res[slot] = 0;
759         }
760 }
761
762 /*
763  * pcibr_initial_rrb
764  *      Assign an equal total number of RRBs to all candidate slots, 
765  *      where the total is the sum of the number of RRBs assigned to
766  *      the normal channel, the number of RRBs assigned to the virtual
767  *      channels, and the number of RRBs assigned as reserved. 
768  *
769  *      A candidate slot is any existing (populated or empty) slot.
770  *      Empty SN1 slots need RRBs to support hot-plug operations.
771  */
772
773 int
774 pcibr_initial_rrb(vertex_hdl_t pcibr_vhdl,
775                              pciio_slot_t first, pciio_slot_t last)
776 {
777     pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
778     bridge_t               *bridge = pcibr_soft->bs_base;
779     pciio_slot_t            slot;
780     int                     rrb_total;
781     int                     vchan_total;
782     int                     vchan;
783     int                     have[2][3];
784     int                     res[2];
785     int                     eo;
786
787     have[0][0] = have[0][1] = have[0][2] = 0;
788     have[1][0] = have[1][1] = have[1][2] = 0;
789     res[0] = res[1] = 0;
790
791     vchan_total = NUMBER_VCHANNELS(bridge);
792
793     for (slot = pcibr_soft->bs_min_slot; 
794                         slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
795         /* Initial RRB management; give back RRBs in all non-existent slots */
796         (void) pcibr_slot_initial_rrb_alloc(pcibr_vhdl, slot);
797
798         /* Base calculations only on existing slots */
799         if ((slot >= first) && (slot <= last)) {
800             rrb_total = 0;
801             for (vchan = 0; vchan < vchan_total; vchan++) 
802                 rrb_total += pcibr_soft->bs_rrb_valid[slot][vchan];
803
804             if (rrb_total < 3)
805                 have[slot & 1][rrb_total]++;
806         }
807     }
808
809     /* Initialize even/odd slot available RRB counts */
810     pcibr_soft->bs_rrb_avail[0] = do_pcibr_rrb_count_avail(bridge, 0);
811     pcibr_soft->bs_rrb_avail[1] = do_pcibr_rrb_count_avail(bridge, 1);
812
813     /*
814      * Calculate reserved RRBs for slots based on current RRB usage
815      */
816     for (eo = 0; eo < 2; eo++) {
817         if ((3 * have[eo][0] + 2 * have[eo][1] + have[eo][2]) <= pcibr_soft->bs_rrb_avail[eo])
818             res[eo] = 3;
819         else if ((2 * have[eo][0] + have[eo][1]) <= pcibr_soft->bs_rrb_avail[eo])
820             res[eo] = 2;
821         else if (have[eo][0] <= pcibr_soft->bs_rrb_avail[eo])
822             res[eo] = 1;
823         else
824             res[eo] = 0;
825
826     }
827
828     /* Assign reserved RRBs to existing slots */
829     for (slot = first; slot <= last; ++slot) {
830         int                     r;
831
832         rrb_total = 0;
833         for (vchan = 0; vchan < vchan_total; vchan++)
834                 rrb_total += pcibr_soft->bs_rrb_valid[slot][vchan];
835
836         r = res[slot & 1] - (rrb_total);
837
838         if (r > 0) {
839             pcibr_soft->bs_rrb_res[slot] = r;
840             pcibr_soft->bs_rrb_avail[slot & 1] -= r;
841         }
842     }
843
844     pcibr_rrb_debug("pcibr_initial_rrb", pcibr_soft);
845
846     return 0;
847
848 }
849
850 /*
851  * Dump the pcibr_soft_t RRB state variable
852  */
853 void
854 pcibr_rrb_debug(char *calling_func, pcibr_soft_t pcibr_soft)
855 {
856     pciio_slot_t slot;
857     char tmp_str[256];
858     
859     if (pcibr_debug_mask & PCIBR_DEBUG_RRB) {
860         PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_soft->bs_vhdl,
861                     "%s: rrbs available, even=%d, odd=%d\n", calling_func,
862                     pcibr_soft->bs_rrb_avail[0], pcibr_soft->bs_rrb_avail[1]));
863
864         if (IS_PIC_SOFT(pcibr_soft)) {
865             PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_soft->bs_vhdl,
866                         "\tslot\tvchan0\tvchan1\tvchan2\tvchan3\treserved\n"));
867         } else {
868             PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_soft->bs_vhdl,
869                         "\tslot\tvchan0\tvchan1\treserved\n"));
870         }
871
872         for (slot=0; slot < PCIBR_NUM_SLOTS(pcibr_soft); slot++) {
873             /*
874              * The kernel only allows functions to have so many variable args,
875              * attempting to call PCIBR_DEBUG_ALWAYS() with more than 5 printf
876              * arguments fails so sprintf() it into a temporary string.
877              */
878             if (IS_PIC_SOFT(pcibr_soft)) {
879                 sprintf(tmp_str, "\t %d\t  %d\t  %d\t  %d\t  %d\t  %d\n", 
880                         PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot),
881                         0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN0],
882                         0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN1],
883                         0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN2],
884                         0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN3],
885                         pcibr_soft->bs_rrb_res[slot]);
886             } else {
887                 sprintf(tmp_str, "\t %d\t  %d\t  %d\t  %d\n", 
888                         PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot),
889                         0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN0],
890                         0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN1],
891                         pcibr_soft->bs_rrb_res[slot]);
892             }
893     
894             PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_soft->bs_vhdl,
895                         "%s", tmp_str));
896         }
897     }
898 }