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