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