~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c

Version: ~ [ linux-5.0-rc6 ] ~ [ linux-4.20.10 ] ~ [ linux-4.19.23 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.101 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.158 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.174 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.134 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.63 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 <linux/pci.h>
 14 #include <asm/sn/sgi.h>
 15 #include <asm/sn/sn_cpuid.h>
 16 #include <asm/sn/addrs.h>
 17 #include <asm/sn/arch.h>
 18 #include <asm/sn/iograph.h>
 19 #include <asm/sn/invent.h>
 20 #include <asm/sn/hcl.h>
 21 #include <asm/sn/labelcl.h>
 22 #include <asm/sn/xtalk/xwidget.h>
 23 #include <asm/sn/pci/bridge.h>
 24 #include <asm/sn/pci/pciio.h>
 25 #include <asm/sn/pci/pcibr.h>
 26 #include <asm/sn/pci/pcibr_private.h>
 27 #include <asm/sn/pci/pci_defs.h>
 28 #include <asm/sn/prio.h>
 29 #include <asm/sn/xtalk/xbow.h>
 30 #include <asm/sn/io.h>
 31 #include <asm/sn/sn_private.h>
 32 
 33 extern pcibr_info_t     pcibr_info_get(vertex_hdl_t);
 34 extern int              pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl);
 35 extern pcibr_info_t     pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
 36 extern int              pcibr_slot_initial_rrb_alloc(vertex_hdl_t,pciio_slot_t);
 37 extern int              pcibr_pcix_rbars_calc(pcibr_soft_t);
 38 
 39 int pcibr_slot_info_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot);
 40 int pcibr_slot_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot);
 41 int pcibr_slot_addr_space_init(vertex_hdl_t pcibr_vhdl,  pciio_slot_t slot);
 42 int pcibr_slot_pcix_rbar_init(pcibr_soft_t pcibr_soft,  pciio_slot_t slot);
 43 int pcibr_slot_device_init(vertex_hdl_t pcibr_vhdl,  pciio_slot_t slot);
 44 int pcibr_slot_guest_info_init(vertex_hdl_t pcibr_vhdl,  pciio_slot_t slot);
 45 int pcibr_slot_call_device_attach(vertex_hdl_t pcibr_vhdl,
 46                  pciio_slot_t slot, int drv_flags);
 47 int pcibr_slot_call_device_detach(vertex_hdl_t pcibr_vhdl,
 48                  pciio_slot_t slot, int drv_flags);
 49 int pcibr_slot_detach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot,
 50                  int drv_flags, char *l1_msg, int *sub_errorp);
 51 static int pcibr_probe_slot(bridge_t *, cfg_p, unsigned int *);
 52 void pcibr_device_info_free(vertex_hdl_t, pciio_slot_t);
 53 iopaddr_t pcibr_bus_addr_alloc(pcibr_soft_t, pciio_win_info_t, 
 54                                pciio_space_t, int, int, int);
 55 void pciibr_bus_addr_free(pcibr_soft_t, pciio_win_info_t);
 56 cfg_p pcibr_find_capability(cfg_p, unsigned);
 57 extern uint64_t  do_pcibr_config_get(cfg_p, unsigned, unsigned);
 58 void do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t); 
 59 
 60 int pcibr_slot_attach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot,
 61                 int drv_flags, char *l1_msg, int *sub_errorp);
 62 
 63 int pcibr_slot_info_return(pcibr_soft_t pcibr_soft, pciio_slot_t slot,
 64                  pcibr_slot_info_resp_t respp);
 65 
 66 extern vertex_hdl_t baseio_pci_vhdl;
 67 int scsi_ctlr_nums_add(vertex_hdl_t, vertex_hdl_t);
 68 
 69 
 70 /* For now .... */
 71 /*
 72  * PCI Hot-Plug Capability Flags
 73 
 74  */
 75 #define D_PCI_HOT_PLUG_ATTACH  0x200  /* Driver supports PCI hot-plug attach */
 76 #define D_PCI_HOT_PLUG_DETACH  0x400  /* Driver supports PCI hot-plug detach */
 77 
 78 
 79 /* 
 80  * PCI-X Max Outstanding Split Transactions translation array and Max Memory
 81  * Read Byte Count translation array, as defined in the PCI-X Specification.
 82  * Section 7.2.3 & 7.2.4 of PCI-X Specification - rev 1.0
 83  */
 84 #define MAX_SPLIT_TABLE 8
 85 #define MAX_READCNT_TABLE 4
 86 int max_splittrans_to_numbuf[MAX_SPLIT_TABLE] = {1, 2, 3, 4, 8, 12, 16, 32};
 87 int max_readcount_to_bufsize[MAX_READCNT_TABLE] = {512, 1024, 2048, 4096 };
 88 
 89 
 90 /*==========================================================================
 91  *      BRIDGE PCI SLOT RELATED IOCTLs
 92  */
 93 
 94 /*
 95  * pcibr_slot_startup
 96  *      Software start-up the PCI slot.
 97  */
 98 
 99 #ifdef PIC_LATER
100 
101 int
102 pcibr_slot_startup(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp)
103 {
104     pcibr_soft_t                   pcibr_soft = pcibr_soft_get(pcibr_vhdl);
105     pciio_slot_t                   slot;
106     int                            error = 0;
107     char                           l1_msg[BRL1_QSIZE+1];
108     struct pcibr_slot_up_resp_s    tmp_up_resp;
109 
110     /* Make sure that we are dealing with a bridge device vertex */
111     if (!pcibr_soft) {
112         return(PCI_NOT_A_BRIDGE);
113     }
114 
115     /* req_slot is the 'external' slot number, convert for internal use */
116     slot = PCIBR_SLOT_TO_DEVICE(pcibr_soft, reqp->req_slot);
117 
118     /* Check for the valid slot */
119     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
120         return(PCI_NOT_A_SLOT);
121 
122 #ifdef PIC_LATER
123     /* Acquire update access to the bus */
124     mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);
125 #endif
126 
127     if (pcibr_soft->bs_slot[slot].slot_status & SLOT_STARTUP_CMPLT) {
128         error = PCI_SLOT_ALREADY_UP;
129         goto startup_unlock;
130     }
131 
132     error = pcibr_slot_attach(pcibr_vhdl, slot, D_PCI_HOT_PLUG_ATTACH,
133                               l1_msg, &tmp_up_resp.resp_sub_errno);
134 
135     strncpy(tmp_up_resp.resp_l1_msg, l1_msg, L1_QSIZE);
136     tmp_up_resp.resp_l1_msg[L1_QSIZE] = '\0';
137 
138     if (COPYOUT(&tmp_up_resp, reqp->req_respp.up, reqp->req_size)) {
139         return(EFAULT);
140     }
141 
142     startup_unlock:
143 
144 #ifdef PIC_LATER
145     /* Release the bus lock */
146     mrunlock(pcibr_soft->bs_bus_lock);
147 #endif
148     return(error);
149 }
150 
151 /*
152  * pcibr_slot_shutdown
153  *      Software shut-down the PCI slot
154  */
155 int
156 pcibr_slot_shutdown(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp)
157 {
158     pcibr_soft_t                   pcibr_soft = pcibr_soft_get(pcibr_vhdl);
159     bridge_t                      *bridge;
160     pciio_slot_t                   slot;
161     int                            error = 0;
162     char                           l1_msg[BRL1_QSIZE+1];
163     struct pcibr_slot_down_resp_s  tmp_down_resp;
164     pciio_slot_t                   tmp_slot;
165 
166     /* Make sure that we are dealing with a bridge device vertex */
167     if (!pcibr_soft) {
168         return(PCI_NOT_A_BRIDGE);
169     }
170 
171     /* req_slot is the 'external' slot number, convert for internal use */
172     slot = PCIBR_SLOT_TO_DEVICE(pcibr_soft, reqp->req_slot);
173 
174     bridge = pcibr_soft->bs_base;
175 
176     /* Check for valid slot */
177     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
178         return(PCI_NOT_A_SLOT);
179 
180 #ifdef PIC_LATER
181     /* Acquire update access to the bus */
182     mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);
183 #endif
184 
185     if ((pcibr_soft->bs_slot[slot].slot_status & SLOT_SHUTDOWN_CMPLT) ||
186         ((pcibr_soft->bs_slot[slot].slot_status & SLOT_STATUS_MASK) == 0)) {
187         error = PCI_SLOT_ALREADY_DOWN;
188         /*
189          * RJR - Should we invoke an L1 slot power-down command just in case
190          *       a previous shut-down failed to power-down the slot?
191          */
192         goto shutdown_unlock;
193     }
194 
195     /* Do not allow a multi-function card to be hot-plug removed */
196     if (pcibr_soft->bs_slot[slot].bss_ninfo > 1) {
197         tmp_down_resp.resp_sub_errno = EPERM;
198         error = PCI_MULTI_FUNC_ERR;
199         goto shutdown_copyout;
200     }
201 
202     /* Do not allow the last 33 MHz card to be removed */
203     if ((bridge->b_wid_control & BRIDGE_CTRL_BUS_SPEED_MASK) ==
204          BRIDGE_CTRL_BUS_SPEED_33) {
205         for (tmp_slot = pcibr_soft->bs_first_slot;
206              tmp_slot <= pcibr_soft->bs_last_slot; tmp_slot++)
207             if (tmp_slot != slot)
208                 if (pcibr_soft->bs_slot[tmp_slot].slot_status & SLOT_POWER_UP) {
209                     error++;
210                     break;
211                 }
212         if (!error) {
213             error = PCI_EMPTY_33MHZ;
214             goto shutdown_unlock;
215         }
216     }
217 
218     error = pcibr_slot_detach(pcibr_vhdl, slot, D_PCI_HOT_PLUG_DETACH,
219                               l1_msg, &tmp_down_resp.resp_sub_errno);
220 
221     strncpy(tmp_down_resp.resp_l1_msg, l1_msg, L1_QSIZE);
222     tmp_down_resp.resp_l1_msg[L1_QSIZE] = '\0';
223 
224     shutdown_copyout:
225 
226     if (COPYOUT(&tmp_down_resp, reqp->req_respp.down, reqp->req_size)) {
227         return(EFAULT);
228     }
229 
230     shutdown_unlock:
231 
232 #ifdef PIC_LATER
233     /* Release the bus lock */
234     mrunlock(pcibr_soft->bs_bus_lock);
235 #endif
236 
237     return(error);
238 }
239 #endif  /* PIC_LATER */
240 
241 char *pci_space_name[] = {"NONE", 
242                           "ROM",
243                           "IO",
244                           "",
245                           "MEM",
246                           "MEM32",
247                           "MEM64",
248                           "CFG",
249                           "WIN0",
250                           "WIN1",
251                           "WIN2",
252                           "WIN3",
253                           "WIN4",
254                           "WIN5",
255                           "",
256                           "BAD"};
257 
258 void
259 pcibr_slot_func_info_return(pcibr_info_h pcibr_infoh,
260                             int func,
261                             pcibr_slot_func_info_resp_t funcp)
262 {
263     pcibr_info_t                 pcibr_info = pcibr_infoh[func];
264     int                          win;
265 
266     funcp->resp_f_status = 0;
267 
268     if (!pcibr_info) {
269         return;
270     }
271 
272     funcp->resp_f_status |= FUNC_IS_VALID;
273 #if defined(SUPPORT_PRINTING_V_FORMAT)
274     sprintf(funcp->resp_f_slot_name, "%v", pcibr_info->f_vertex);
275 #endif
276 
277     funcp->resp_f_bus = pcibr_info->f_bus;
278     funcp->resp_f_slot = PCIBR_INFO_SLOT_GET_EXT(pcibr_info);
279     funcp->resp_f_func = pcibr_info->f_func;
280 #if defined(SUPPORT_PRINTING_V_FORMAT)
281     sprintf(funcp->resp_f_master_name, "%v", pcibr_info->f_master);
282 #endif
283     funcp->resp_f_pops = pcibr_info->f_pops;
284     funcp->resp_f_efunc = pcibr_info->f_efunc;
285     funcp->resp_f_einfo = pcibr_info->f_einfo;
286 
287     funcp->resp_f_vendor = pcibr_info->f_vendor;
288     funcp->resp_f_device = pcibr_info->f_device;
289 
290     for(win = 0 ; win < 6 ; win++) {
291         funcp->resp_f_window[win].resp_w_base =
292                                   pcibr_info->f_window[win].w_base;
293         funcp->resp_f_window[win].resp_w_size =
294                                   pcibr_info->f_window[win].w_size;
295         sprintf(funcp->resp_f_window[win].resp_w_space,
296                 "%s",
297                 pci_space_name[pcibr_info->f_window[win].w_space]);
298     }
299 
300     funcp->resp_f_rbase = pcibr_info->f_rbase;
301     funcp->resp_f_rsize = pcibr_info->f_rsize;
302 
303     for (win = 0 ; win < 4; win++) {
304         funcp->resp_f_ibit[win] = pcibr_info->f_ibit[win];
305     }
306 
307     funcp->resp_f_att_det_error = pcibr_info->f_att_det_error;
308 
309 }
310 
311 int
312 pcibr_slot_info_return(pcibr_soft_t             pcibr_soft,
313                        pciio_slot_t             slot,
314                        pcibr_slot_info_resp_t   respp)
315 {
316     pcibr_soft_slot_t            pss;
317     int                          func;
318     bridge_t                    *bridge = pcibr_soft->bs_base;
319     reg_p                        b_respp;
320     pcibr_slot_info_resp_t       slotp;
321     pcibr_slot_func_info_resp_t  funcp;
322     extern void snia_kmem_free(void *, int);
323 
324     slotp = snia_kmem_zalloc(sizeof(*slotp), 0);
325     if (slotp == NULL) {
326         return(ENOMEM);
327     }
328 
329     pss = &pcibr_soft->bs_slot[slot];
330 
331     slotp->resp_bs_bridge_mode = pcibr_soft->bs_bridge_mode;
332     slotp->resp_bs_bridge_type = pcibr_soft->bs_bridge_type;
333 
334     slotp->resp_has_host = pss->has_host;
335     slotp->resp_host_slot = pss->host_slot;
336 #if defined(SUPPORT_PRINTING_V_FORMAT)
337     sprintf(slotp->resp_slot_conn_name, "%v", pss->slot_conn);
338 #else
339     sprintf(slotp->resp_slot_conn_name, "%p", (void *)pss->slot_conn);
340 #endif
341     slotp->resp_slot_status = pss->slot_status;
342 
343     slotp->resp_l1_bus_num = pcibr_widget_to_bus(pcibr_soft->bs_vhdl);
344     slotp->resp_bss_ninfo = pss->bss_ninfo;
345 
346     for (func = 0; func < pss->bss_ninfo; func++) {
347         funcp = &(slotp->resp_func[func]);
348         pcibr_slot_func_info_return(pss->bss_infos, func, funcp);
349     }
350 
351     sprintf(slotp->resp_bss_devio_bssd_space, "%s",
352             pci_space_name[pss->bss_devio.bssd_space]);
353     slotp->resp_bss_devio_bssd_base = pss->bss_devio.bssd_base;
354     slotp->resp_bss_device = pss->bss_device;
355 
356     slotp->resp_bss_pmu_uctr = pss->bss_pmu_uctr;
357     slotp->resp_bss_d32_uctr = pss->bss_d32_uctr;
358     slotp->resp_bss_d64_uctr = pss->bss_d64_uctr;
359 
360     slotp->resp_bss_d64_base = pss->bss_d64_base;
361     slotp->resp_bss_d64_flags = pss->bss_d64_flags;
362     slotp->resp_bss_d32_base = pss->bss_d32_base;
363     slotp->resp_bss_d32_flags = pss->bss_d32_flags;
364 
365     slotp->resp_bss_ext_ates_active = pss->bss_ext_ates_active;
366 
367     slotp->resp_bss_cmd_pointer = pss->bss_cmd_pointer;
368     slotp->resp_bss_cmd_shadow = pss->bss_cmd_shadow;
369 
370     slotp->resp_bs_rrb_valid = pcibr_soft->bs_rrb_valid[slot][VCHAN0];
371     slotp->resp_bs_rrb_valid_v1 = pcibr_soft->bs_rrb_valid[slot][VCHAN1];
372     slotp->resp_bs_rrb_valid_v2 = pcibr_soft->bs_rrb_valid[slot][VCHAN2];
373     slotp->resp_bs_rrb_valid_v3 = pcibr_soft->bs_rrb_valid[slot][VCHAN3];
374     slotp->resp_bs_rrb_res = pcibr_soft->bs_rrb_res[slot];
375 
376     if (slot & 1) {
377         b_respp = &bridge->b_odd_resp;
378     } else {
379         b_respp = &bridge->b_even_resp;
380     }
381 
382     slotp->resp_b_resp = *b_respp;
383 
384     slotp->resp_b_int_device = bridge->b_int_device;
385 
386     if (IS_PIC_SOFT(pcibr_soft)) {
387         slotp->resp_p_int_enable = bridge->p_int_enable_64;
388         slotp->resp_p_int_host = bridge->p_int_addr_64[slot];
389     } else {
390         slotp->resp_b_int_enable = bridge->b_int_enable;
391         slotp->resp_b_int_host = bridge->b_int_addr[slot].addr;
392     }
393 
394     if (COPYOUT(slotp, respp, sizeof(*respp))) {
395         return(EFAULT);
396     }
397 
398     snia_kmem_free(slotp, sizeof(*slotp));
399 
400     return(0);
401 }
402 
403 /*
404  * pcibr_slot_query
405  *      Return information about the PCI slot maintained by the infrastructure.
406  *      Information is requested in the request structure.
407  *
408  *      Information returned in the response structure:
409  *              Slot hwgraph name
410  *              Vendor/Device info
411  *              Base register info
412  *              Interrupt mapping from device pins to the bridge pins
413  *              Devio register
414  *              Software RRB info
415  *              RRB register info
416  *              Host/Gues info
417  *              PCI Bus #,slot #, function #
418  *              Slot provider hwgraph name
419  *              Provider Functions
420  *              Error handler
421  *              DMA mapping usage counters
422  *              DMA direct translation info
423  *              External SSRAM workaround info
424  */
425 int
426 pcibr_slot_query(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp)
427 {
428     pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
429     pciio_slot_t            slot;
430     pciio_slot_t            tmp_slot;
431     pcibr_slot_info_resp_t  respp = reqp->req_respp.query;
432     int                     size = reqp->req_size;
433     int                     error = 0;
434 
435     /* Make sure that we are dealing with a bridge device vertex */
436     if (!pcibr_soft) {
437         return(PCI_NOT_A_BRIDGE);
438     }
439 
440     /* req_slot is the 'external' slot number, convert for internal use */
441     slot = PCIBR_SLOT_TO_DEVICE(pcibr_soft, reqp->req_slot);
442 
443     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HOTPLUG, pcibr_vhdl,
444                 "pcibr_slot_query: pcibr_soft=0x%x, slot=%d, reqp=0x%x\n",
445                 pcibr_soft, slot, reqp));
446 
447     /* Make sure that we have a valid PCI slot number or PCIIO_SLOT_NONE */
448     if ((!PCIBR_VALID_SLOT(pcibr_soft, slot)) && (slot != PCIIO_SLOT_NONE)) {
449         return(PCI_NOT_A_SLOT);
450     }
451 
452     /* Return information for the requested PCI slot */
453     if (slot != PCIIO_SLOT_NONE) {
454         if (size < sizeof(*respp)) {
455             return(PCI_RESP_AREA_TOO_SMALL);
456         }
457 
458 #ifdef PIC_LATER
459         /* Acquire read access to the bus */
460         mrlock(pcibr_soft->bs_bus_lock, MR_ACCESS, PZERO);
461 #endif
462         error = pcibr_slot_info_return(pcibr_soft, slot, respp);
463 
464 #ifdef PIC_LATER
465         /* Release the bus lock */
466         mrunlock(pcibr_soft->bs_bus_lock);
467 #endif
468         return(error);
469     }
470 
471     /* Return information for all the slots */
472     for (tmp_slot = pcibr_soft->bs_min_slot; 
473                 tmp_slot < PCIBR_NUM_SLOTS(pcibr_soft); tmp_slot++) {
474 
475         if (size < sizeof(*respp)) {
476             return(PCI_RESP_AREA_TOO_SMALL);
477         }
478 
479 #ifdef PIC_LATER
480         /* Acquire read access to the bus */
481         mrlock(pcibr_soft->bs_bus_lock, MR_ACCESS, PZERO);
482 #endif
483         error = pcibr_slot_info_return(pcibr_soft, tmp_slot, respp);
484 
485 #ifdef PCI_LATER
486         /* Release the bus lock */
487         mrunlock(pcibr_soft->bs_bus_lock);
488 #endif
489         if (error) {
490             return(error);
491         }
492 
493         ++respp;
494         size -= sizeof(*respp);
495     }
496 
497     return(error);
498 }
499 
500 #define PROBE_LOCK 0    /* FIXME: we're attempting to lock around accesses
501                          * to b_int_enable.   This hangs pcibr_probe_slot()
502                          */
503 
504 /*
505  * pcibr_slot_info_init
506  *      Probe for this slot and see if it is populated.
507  *      If it is populated initialize the generic PCI infrastructural
508  *      information associated with this particular PCI device.
509  */
510 int
511 pcibr_slot_info_init(vertex_hdl_t       pcibr_vhdl,
512                      pciio_slot_t       slot)
513 {
514     pcibr_soft_t            pcibr_soft;
515     pcibr_info_h            pcibr_infoh;
516     pcibr_info_t            pcibr_info;
517     bridge_t               *bridge;
518     cfg_p                   cfgw;
519     unsigned                idword;
520     unsigned                pfail;
521     unsigned                idwords[8];
522     pciio_vendor_id_t       vendor;
523     pciio_device_id_t       device;
524     unsigned                htype;
525     unsigned                lt_time;
526     int                     nbars;
527     cfg_p                   wptr;
528     cfg_p                   pcix_cap;
529     int                     win;
530     pciio_space_t           space;
531     int                     nfunc;
532     pciio_function_t        rfunc;
533     int                     func;
534     vertex_hdl_t            conn_vhdl;
535     pcibr_soft_slot_t       slotp;
536     
537     /* Get the basic software information required to proceed */
538     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
539     if (!pcibr_soft)
540         return(EINVAL);
541 
542     bridge = pcibr_soft->bs_base;
543     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
544         return(EINVAL);
545 
546     /* If we have a host slot (eg:- IOC3 has 2 PCI slots and the initialization
547      * is done by the host slot then we are done.
548      */
549     if (pcibr_soft->bs_slot[slot].has_host) {
550         return(0);    
551     }
552 
553     /* Try to read the device-id/vendor-id from the config space */
554     cfgw = pcibr_slot_config_addr(bridge, slot, 0);
555 
556 #if PROBE_LOCK
557     s = pcibr_lock(pcibr_soft);
558 #endif
559     if (pcibr_probe_slot(bridge, cfgw, &idword)) 
560         return(ENODEV);
561 #if PROBE_LOCK
562     pcibr_unlock(pcibr_soft, s);
563 #endif
564 
565     slotp = &pcibr_soft->bs_slot[slot];
566     slotp->slot_status |= SLOT_POWER_UP;
567 
568     vendor = 0xFFFF & idword;
569     device = 0xFFFF & (idword >> 16);
570 
571     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_PROBE, pcibr_vhdl,
572                 "pcibr_slot_info_init: slot=%d, vendor=0x%x, device=0x%x\n",
573                 PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), vendor, device));
574 
575     /* If the vendor id is not valid then the slot is not populated
576      * and we are done.
577      */
578     if (vendor == 0xFFFF) 
579         return(ENODEV);                 
580     
581     htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
582     nfunc = 1;
583     rfunc = PCIIO_FUNC_NONE;
584     pfail = 0;
585 
586     /* NOTE: if a card claims to be multifunction
587      * but only responds to config space 0, treat
588      * it as a unifunction card.
589      */
590 
591     if (htype & 0x80) {         /* MULTIFUNCTION */
592         for (func = 1; func < 8; ++func) {
593             cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0);
594 #if PROBE_LOCK
595             s = pcibr_lock(pcibr_soft);
596 #endif
597             if (pcibr_probe_slot(bridge, cfgw, &idwords[func])) {
598                 pfail |= 1 << func;
599                 continue;
600             }
601 #if PROBE_LOCK
602             pcibr_unlock(pcibr_soft, s);
603 #endif
604             vendor = 0xFFFF & idwords[func];
605             if (vendor == 0xFFFF) {
606                 pfail |= 1 << func;
607                 continue;
608             }
609             nfunc = func + 1;
610             rfunc = 0;
611         }
612         cfgw = pcibr_slot_config_addr(bridge, slot, 0);
613     }
614     NEWA(pcibr_infoh, nfunc);
615     
616     pcibr_soft->bs_slot[slot].bss_ninfo = nfunc;
617     pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
618 
619     for (func = 0; func < nfunc; ++func) {
620         unsigned                cmd_reg;
621         
622         if (func) {
623             if (pfail & (1 << func))
624                 continue;
625             
626             idword = idwords[func];
627             cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0);
628             
629             device = 0xFFFF & (idword >> 16);
630             htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
631             rfunc = func;
632         }
633         htype &= 0x7f;
634         if (htype != 0x00) {
635             printk(KERN_WARNING 
636                 "%s pcibr: pci slot %d func %d has strange header type 0x%x\n",
637                     pcibr_soft->bs_name, slot, func, htype);
638             nbars = 2;
639         } else {
640             nbars = PCI_CFG_BASE_ADDRS;
641         }
642 
643         PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_CONFIG, pcibr_vhdl,
644                 "pcibr_slot_info_init: slot=%d, func=%d, cfgw=0x%x\n",
645                 PCIBR_DEVICE_TO_SLOT(pcibr_soft,slot), func, cfgw));
646 
647 #ifdef PIC_LATER
648         /*
649          * Check for a Quad ATM PCI "card" and return all the PCI bus
650          * memory and I/O space.  This will work-around an apparent
651          * hardware problem with the Quad ATM XIO card handling large
652          * PIO addresses.  Releasing all the space for use by the card
653          * will lower the PIO addresses with the PCI bus address space.
654          * This is OK since the PROM did not assign any BAR addresses. 
655          *
656          * Only release all the PCI bus addresses once.
657          *
658          */
659         if ((vendor == LINC_VENDOR_ID_NUM) && (device == LINC_DEVICE_ID_NUM)) {
660             iopaddr_t               prom_base_addr = pcibr_soft->bs_xid << 24;
661             int                     prom_base_size = 0x1000000;
662 
663             if (!(pcibr_soft->bs_bus_addr_status & PCIBR_BUS_ADDR_MEM_FREED)) {
664                 pciio_device_win_populate(&pcibr_soft->bs_mem_win_map,
665                                           prom_base_addr, prom_base_size);
666                 pcibr_soft->bs_bus_addr_status |= PCIBR_BUS_ADDR_MEM_FREED;
667             }
668 
669             if (!(pcibr_soft->bs_bus_addr_status & PCIBR_BUS_ADDR_IO_FREED)) {
670                 pciio_device_win_populate(&pcibr_soft->bs_io_win_map,
671                                           prom_base_addr, prom_base_size);
672                 pcibr_soft->bs_bus_addr_status |= PCIBR_BUS_ADDR_IO_FREED;
673             }
674         }
675 #endif  /* PIC_LATER */
676 
677         /* 
678          * If the latency timer has already been set, by prom or by the
679          * card itself, use that value.  Otherwise look at the device's
680          * 'min_gnt' and attempt to calculate a latency time. 
681          *
682          * NOTE: For now if the device is on the 'real time' arbitration
683          * ring we don't set the latency timer.  
684          *
685          * WAR: SGI's IOC3 and RAD devices target abort if you write a 
686          * single byte into their config space.  So don't set the Latency
687          * Timer for these devices
688          */
689 
690         lt_time = do_pcibr_config_get(cfgw, PCI_CFG_LATENCY_TIMER, 1);
691 
692         if ((lt_time == 0) && !(bridge->b_device[slot].reg & BRIDGE_DEV_RT) &&
693                                        (device == 0x5 /* RAD_DEV */)) {
694              unsigned   min_gnt;
695              unsigned   min_gnt_mult;
696             
697             /* 'min_gnt' indicates how long of a burst period a device
698              * needs in increments of 250ns.  But latency timer is in
699              * PCI clock cycles, so a conversion is needed.
700              */
701             min_gnt = do_pcibr_config_get(cfgw, PCI_MIN_GNT, 1);
702 
703             if (IS_133MHZ(pcibr_soft))
704                 min_gnt_mult = 32;      /* 250ns @ 133MHz in clocks */
705             else if (IS_100MHZ(pcibr_soft))
706                 min_gnt_mult = 24;      /* 250ns @ 100MHz in clocks */
707             else if (IS_66MHZ(pcibr_soft))
708                 min_gnt_mult = 16;      /* 250ns @ 66MHz, in clocks */
709             else
710                 min_gnt_mult = 8;       /* 250ns @ 33MHz, in clocks */
711 
712             if ((min_gnt != 0) && ((min_gnt * min_gnt_mult) < 256))
713                 lt_time = (min_gnt * min_gnt_mult);
714             else
715                 lt_time = 4 * min_gnt_mult;       /* 1 micro second */
716 
717             do_pcibr_config_set(cfgw, PCI_CFG_LATENCY_TIMER, 1, lt_time);
718 
719             PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_CONFIG, pcibr_vhdl,
720                     "pcibr_slot_info_init: set Latency Timer for slot=%d, "
721                     "func=%d, to 0x%x\n", 
722                     PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), func, lt_time));
723         }
724 
725 
726         /* In our architecture the setting of the cacheline size isn't 
727          * beneficial for cards in PCI mode, but in PCI-X mode devices
728          * can optionally use the cacheline size value for internal 
729          * device optimizations    (See 7.1.5 of the PCI-X v1.0 spec).
730          * NOTE: cachline size is in doubleword increments
731          */
732         if (IS_PCIX(pcibr_soft)) {
733             if (!do_pcibr_config_get(cfgw, PCI_CFG_CACHE_LINE, 1)) {
734                 do_pcibr_config_set(cfgw, PCI_CFG_CACHE_LINE, 1, 0x20);
735                 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_CONFIG, pcibr_vhdl,
736                         "pcibr_slot_info_init: set CacheLine for slot=%d, "
737                         "func=%d, to 0x20\n",
738                         PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), func));
739             }
740 
741             /* Get the PCI-X capability if running in PCI-X mode.  If the func
742              * doesnt have a pcix capability, allocate a PCIIO_VENDOR_ID_NONE
743              * pcibr_info struct so the device driver for that function is not
744              * called.
745              */
746             if (!(pcix_cap = pcibr_find_capability(cfgw, PCI_CAP_PCIX))) {
747                 printk(KERN_WARNING
748 #if defined(SUPPORT_PRINTING_V_FORMAT)
749                         "%v: Bus running in PCI-X mode, But card in slot %d, "
750                         "func %d not PCI-X capable\n", pcibr_vhdl, slot, func);
751 #else
752                         "0x%lx: Bus running in PCI-X mode, But card in slot %d, "
753                         "func %d not PCI-X capable\n", (unsigned long)pcibr_vhdl, slot, func);
754 #endif
755                 pcibr_device_info_new(pcibr_soft, slot, PCIIO_FUNC_NONE,
756                                PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
757                 continue;
758             }
759             PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_CONFIG, pcibr_vhdl,
760                     "pcibr_slot_info_init: PCI-X capability at 0x%x for "
761                     "slot=%d, func=%d\n", 
762                     pcix_cap, PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), func));
763         } else {
764             pcix_cap = NULL;
765         }
766 
767         pcibr_info = pcibr_device_info_new
768             (pcibr_soft, slot, rfunc, vendor, device);
769 
770         /* Keep a running total of the number of PIC-X functions on the bus
771          * and the number of max outstanding split trasnactions that they
772          * have requested.  NOTE: "pcix_cap != NULL" implies IS_PCIX()
773          */
774         pcibr_info->f_pcix_cap = (cap_pcix_type0_t *)pcix_cap;
775         if (pcibr_info->f_pcix_cap) {
776             int max_out;      /* max outstanding splittrans from status reg */
777 
778             pcibr_soft->bs_pcix_num_funcs++;
779             max_out = pcibr_info->f_pcix_cap->pcix_type0_status.max_out_split;
780             pcibr_soft->bs_pcix_split_tot += max_splittrans_to_numbuf[max_out];
781         }
782 
783         conn_vhdl = pciio_device_info_register(pcibr_vhdl, &pcibr_info->f_c);
784         if (func == 0)
785             slotp->slot_conn = conn_vhdl;
786 
787         cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4);
788         
789         wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
790 
791         for (win = 0; win < nbars; ++win) {
792             iopaddr_t               base, mask, code;
793             size_t                  size;
794 
795             /*
796              * GET THE BASE & SIZE OF THIS WINDOW:
797              *
798              * The low two or four bits of the BASE register
799              * determines which address space we are in; the
800              * rest is a base address. BASE registers
801              * determine windows that are power-of-two sized
802              * and naturally aligned, so we can get the size
803              * of a window by writing all-ones to the
804              * register, reading it back, and seeing which
805              * bits are used for decode; the least
806              * significant nonzero bit is also the size of
807              * the window.
808              *
809              * WARNING: someone may already have allocated
810              * some PCI space to this window, and in fact
811              * PIO may be in process at this very moment
812              * from another processor (or even from this
813              * one, if we get interrupted)! So, if the BASE
814              * already has a nonzero address, be generous
815              * and use the LSBit of that address as the
816              * size; this could overstate the window size.
817              * Usually, when one card is set up, all are set
818              * up; so, since we don't bitch about
819              * overlapping windows, we are ok.
820              *
821              * UNFORTUNATELY, some cards do not clear their
822              * BASE registers on reset. I have two heuristics
823              * that can detect such cards: first, if the
824              * decode enable is turned off for the space
825              * that the window uses, we can disregard the
826              * initial value. second, if the address is
827              * outside the range that we use, we can disregard
828              * it as well.
829              *
830              * This is looking very PCI generic. Except for
831              * knowing how many slots and where their config
832              * spaces are, this window loop and the next one
833              * could probably be shared with other PCI host
834              * adapters. It would be interesting to see if
835              * this could be pushed up into pciio, when we
836              * start supporting more PCI providers.
837              */
838             base = do_pcibr_config_get(wptr, (win * 4), 4);
839 
840             if (base & PCI_BA_IO_SPACE) {
841                 /* BASE is in I/O space. */
842                 space = PCIIO_SPACE_IO;
843                 mask = -4;
844                 code = base & 3;
845                 base = base & mask;
846                 if (base == 0) {
847                     ;           /* not assigned */
848                 } else if (!(cmd_reg & PCI_CMD_IO_SPACE)) {
849                     base = 0;   /* decode not enabled */
850                 }
851             } else {
852                 /* BASE is in MEM space. */
853                 space = PCIIO_SPACE_MEM;
854                 mask = -16;
855                 code = base & PCI_BA_MEM_LOCATION;      /* extract BAR type */
856                 base = base & mask;
857                 if (base == 0) {
858                     ;           /* not assigned */
859                 } else if (!(cmd_reg & PCI_CMD_MEM_SPACE)) {
860                     base = 0;   /* decode not enabled */
861                 } else if (base & 0xC0000000) {
862                     base = 0;   /* outside permissable range */
863                 } else if ((code == PCI_BA_MEM_64BIT) &&
864                            (do_pcibr_config_get(wptr, ((win + 1)*4), 4) != 0)) {
865                     base = 0;   /* outside permissable range */
866                 }
867             }
868 
869             if (base != 0) {    /* estimate size */
870                 size = base & -base;
871             } else {            /* calculate size */
872                 do_pcibr_config_set(wptr, (win * 4), 4, ~0);    /* write 1's */
873                 size = do_pcibr_config_get(wptr, (win * 4), 4); /* read back */
874                 size &= mask;   /* keep addr */
875                 size &= -size;  /* keep lsbit */
876                 if (size == 0)
877                     continue;
878             }   
879 
880             pcibr_info->f_window[win].w_space = space;
881             pcibr_info->f_window[win].w_base = base;
882             pcibr_info->f_window[win].w_size = size;
883 
884             if (code == PCI_BA_MEM_64BIT) {
885                 win++;          /* skip upper half */
886                 do_pcibr_config_set(wptr, (win * 4), 4, 0);  /* must be zero */
887             }
888         }                               /* next win */
889     }                           /* next func */
890 
891     return(0);
892 }                                       
893 
894 /*
895  * pcibr_find_capability
896  *      Walk the list of capabilities (if it exists) looking for
897  *      the requested capability.  Return a cfg_p pointer to the
898  *      capability if found, else return NULL
899  */
900 cfg_p
901 pcibr_find_capability(cfg_p     cfgw,
902                       unsigned  capability)
903 {
904     unsigned            cap_nxt;
905     unsigned            cap_id;
906     int                 defend_against_circular_linkedlist = 0;
907 
908     /* Check to see if there is a capabilities pointer in the cfg header */
909     if (!(do_pcibr_config_get(cfgw, PCI_CFG_STATUS, 2) & PCI_STAT_CAP_LIST)) {
910         return (NULL);
911     }
912 
913     /*
914      * Read up the capabilities head pointer from the configuration header.
915      * Capabilities are stored as a linked list in the lower 48 dwords of
916      * config space and are dword aligned. (Note: spec states the least two
917      * significant bits of the next pointer must be ignored,  so we mask
918      * with 0xfc).
919      */
920     cap_nxt = (do_pcibr_config_get(cfgw, PCI_CAPABILITIES_PTR, 1) & 0xfc);
921 
922     while (cap_nxt && (defend_against_circular_linkedlist <= 48)) {
923         cap_id = do_pcibr_config_get(cfgw, cap_nxt, 1);
924         if (cap_id == capability) {
925             return ((cfg_p)((char *)cfgw + cap_nxt));
926         }
927         cap_nxt = (do_pcibr_config_get(cfgw, cap_nxt+1, 1) & 0xfc);
928         defend_against_circular_linkedlist++;
929     }
930 
931     return (NULL);
932 }
933 
934 /*
935  * pcibr_slot_info_free
936  *      Remove all the PCI infrastructural information associated
937  *      with a particular PCI device.
938  */
939 int
940 pcibr_slot_info_free(vertex_hdl_t pcibr_vhdl,
941                      pciio_slot_t slot)
942 {
943     pcibr_soft_t        pcibr_soft;
944     pcibr_info_h        pcibr_infoh;
945     int                 nfunc;
946 
947     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
948 
949     if (!pcibr_soft)
950         return(EINVAL);
951 
952     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
953         return(EINVAL);
954 
955     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
956 
957     pcibr_device_info_free(pcibr_vhdl, slot);
958 
959     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
960     DELA(pcibr_infoh,nfunc);
961     pcibr_soft->bs_slot[slot].bss_ninfo = 0;
962 
963     return(0);
964 }
965 
966 /*
967  * pcibr_slot_pcix_rbar_init
968  *      Allocate RBARs to the PCI-X functions on a given device
969  */
970 int
971 pcibr_slot_pcix_rbar_init(pcibr_soft_t pcibr_soft,
972                             pciio_slot_t slot)
973 {
974     pcibr_info_h         pcibr_infoh;
975     pcibr_info_t         pcibr_info;
976     char                 tmp_str[256];
977     int                  nfunc;
978     int                  func;
979 
980     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
981         return(EINVAL);
982 
983     if ((nfunc = pcibr_soft->bs_slot[slot].bss_ninfo) < 1)
984         return(EINVAL);
985 
986     if (!(pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos))
987         return(EINVAL);
988 
989     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RBAR, pcibr_soft->bs_vhdl,
990                 "pcibr_slot_pcix_rbar_init for slot %d\n", 
991                 PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot)));
992     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RBAR, pcibr_soft->bs_vhdl,
993                 "\tslot/func\trequested\tgiven\tinuse\tavail\n"));
994 
995     for (func = 0; func < nfunc; ++func) {
996         cap_pcix_type0_t        *pcix_cap_p;
997         cap_pcix_stat_reg_t     *pcix_statreg_p;
998         cap_pcix_cmd_reg_t      *pcix_cmdreg_p;
999         int                      num_rbar;
1000 
1001         if (!(pcibr_info = pcibr_infoh[func]))
1002             continue;
1003 
1004         if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
1005             continue;
1006 
1007         if (!(pcix_cap_p = pcibr_info->f_pcix_cap))
1008             continue;
1009 
1010         pcix_statreg_p = &pcix_cap_p->pcix_type0_status;
1011         pcix_cmdreg_p = &pcix_cap_p->pcix_type0_command;
1012 
1013         /* If there are enough RBARs to satify the number of "max outstanding 
1014          * transactions" each function requested (bs_pcix_rbar_percent_allowed
1015          * is 100%), then give each function what it requested, otherwise give 
1016          * the functions a "percentage of what they requested".
1017          */
1018         if (pcibr_soft->bs_pcix_rbar_percent_allowed >= 100) {
1019             pcix_cmdreg_p->max_split = pcix_statreg_p->max_out_split;
1020             num_rbar = max_splittrans_to_numbuf[pcix_cmdreg_p->max_split];
1021             pcibr_soft->bs_pcix_rbar_inuse += num_rbar;
1022             pcibr_soft->bs_pcix_rbar_avail -= num_rbar;
1023             pcix_cmdreg_p->max_mem_read_cnt = pcix_statreg_p->max_mem_read_cnt;
1024         } else {
1025             int index;      /* index into max_splittrans_to_numbuf table */
1026             int max_out;    /* max outstanding transactions given to func */
1027 
1028             /* Calculate the percentage of RBARs this function can have.
1029              * NOTE: Every function gets at least 1 RBAR (thus the "+1").
1030              * bs_pcix_rbar_percent_allowed is the percentage of what was
1031              * requested less this 1 RBAR that all functions automatically 
1032              * gets
1033              */
1034             max_out = ((max_splittrans_to_numbuf[pcix_statreg_p->max_out_split]
1035                         * pcibr_soft->bs_pcix_rbar_percent_allowed) / 100) + 1;
1036 
1037             /* round down the newly caclulated max_out to a valid number in
1038              * max_splittrans_to_numbuf[]
1039              */
1040             for (index = 0; index < MAX_SPLIT_TABLE-1; index++)
1041                 if (max_splittrans_to_numbuf[index + 1] > max_out)
1042                     break;
1043 
1044             pcix_cmdreg_p->max_split = index;
1045             num_rbar = max_splittrans_to_numbuf[pcix_cmdreg_p->max_split];
1046             pcibr_soft->bs_pcix_rbar_inuse += num_rbar;
1047             pcibr_soft->bs_pcix_rbar_avail -= num_rbar;
1048             pcix_cmdreg_p->max_mem_read_cnt = pcix_statreg_p->max_mem_read_cnt;
1049         }
1050         /*
1051          * The kernel only allows functions to have so many variable args,
1052          * attempting to call PCIBR_DEBUG_ALWAYS() with more than 5 printf
1053          * arguments fails so sprintf() it into a temporary string.
1054          */
1055         if (pcibr_debug_mask & PCIBR_DEBUG_RBAR) {
1056             sprintf(tmp_str,"\t  %d/%d   \t    %d    \t  %d  \t  %d  \t  %d\n",
1057                     PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), func,
1058                     max_splittrans_to_numbuf[pcix_statreg_p->max_out_split],
1059                     max_splittrans_to_numbuf[pcix_cmdreg_p->max_split],
1060                     pcibr_soft->bs_pcix_rbar_inuse, 
1061                     pcibr_soft->bs_pcix_rbar_avail);
1062             PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RBAR, pcibr_soft->bs_vhdl, 
1063                         "%s", tmp_str));
1064         }
1065     }
1066     return(0);
1067 }
1068 
1069 int as_debug = 0;
1070 /*
1071  * pcibr_slot_addr_space_init
1072  *      Reserve chunks of PCI address space as required by 
1073  *      the base registers in the card.
1074  */
1075 int
1076 pcibr_slot_addr_space_init(vertex_hdl_t pcibr_vhdl,
1077                            pciio_slot_t slot)
1078 {
1079     pcibr_soft_t         pcibr_soft;
1080     pcibr_info_h         pcibr_infoh;
1081     pcibr_info_t         pcibr_info;
1082     bridge_t            *bridge;
1083     iopaddr_t            mask;
1084     int                  nbars;
1085     int                  nfunc;
1086     int                  func;
1087     int                  win;
1088     int                  rc = 0;
1089     int                  align;
1090     int                  align_slot;
1091 
1092     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
1093 
1094     if (!pcibr_soft)
1095         return(EINVAL);
1096 
1097     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
1098         return(EINVAL);
1099 
1100     bridge = pcibr_soft->bs_base;
1101 
1102     /* allocate address space,
1103      * for windows that have not been
1104      * previously assigned.
1105      */
1106     if (pcibr_soft->bs_slot[slot].has_host) {
1107         return(0);
1108     }
1109 
1110     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
1111     if (nfunc < 1)
1112         return(EINVAL);
1113 
1114     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
1115     if (!pcibr_infoh)
1116         return(EINVAL);
1117 
1118     /*
1119      * Try to make the DevIO windows not
1120      * overlap by pushing the "io" and "hi"
1121      * allocation areas up to the next one
1122      * or two megabyte bound. This also
1123      * keeps them from being zero.
1124      *
1125      * DO NOT do this with "pci_lo" since
1126      * the entire "lo" area is only a
1127      * megabyte, total ...
1128      */
1129     align_slot = 0x100000;
1130     align = align_slot;
1131 
1132     for (func = 0; func < nfunc; ++func) {
1133         cfg_p                   cfgw;
1134         cfg_p                   wptr;
1135         pciio_space_t           space;
1136         iopaddr_t               base;
1137         size_t                  size;
1138 #ifdef PCI_LATER
1139         char                    tmp_str[256];
1140 #endif
1141         unsigned                pci_cfg_cmd_reg;
1142         unsigned                pci_cfg_cmd_reg_add = 0;
1143 
1144         pcibr_info = pcibr_infoh[func];
1145 
1146         if (!pcibr_info)
1147             continue;
1148 
1149         if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
1150             continue;
1151         
1152         cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0);
1153         wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
1154 
1155         if ((do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1) & 0x7f) != 0)
1156             nbars = 2;
1157         else
1158             nbars = PCI_CFG_BASE_ADDRS;
1159 
1160         for (win = 0; win < nbars; ++win) {
1161             space = pcibr_info->f_window[win].w_space;
1162             base = pcibr_info->f_window[win].w_base;
1163             size = pcibr_info->f_window[win].w_size;
1164             
1165             if (size < 1)
1166                 continue;
1167 
1168             if (base >= size) {
1169                 /*
1170                  * The kernel only allows functions to have so many variable
1171                  * args attempting to call PCIBR_DEBUG_ALWAYS() with more than
1172                  * 5 printf arguments fails so sprintf() it into a temporary 
1173                  * string (tmp_str).
1174                  */
1175 #if defined(SUPPORT_PRINTING_R_FORMAT)
1176                 if (pcibr_debug_mask & PCIBR_DEBUG_BAR) {
1177                     sprintf(tmp_str, "pcibr_slot_addr_space_init: slot=%d, "
1178                         "func=%d win %d is in %r [0x%x..0x%x], allocated by "
1179                         "prom\n", PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot),
1180                         func, win, space, space_desc, base, base + size - 1);
1181                     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_BAR, pcibr_vhdl, 
1182                                 "%s",tmp_str));
1183                 }
1184 #endif  /* SUPPORT_PRINTING_R_FORMAT */
1185                 continue;               /* already allocated */
1186             }
1187 
1188             align = (win) ? size : align_slot; 
1189 
1190             if (align < _PAGESZ)
1191                 align = _PAGESZ;        /* ie. 0x00004000 */
1192  
1193             switch (space) {
1194             case PCIIO_SPACE_IO:
1195                 base = pcibr_bus_addr_alloc(pcibr_soft,
1196                                             &pcibr_info->f_window[win],
1197                                             PCIIO_SPACE_IO,
1198                                             0, size, align);
1199                 if (!base)
1200                     rc = ENOSPC;
1201                 break;
1202                 
1203             case PCIIO_SPACE_MEM:
1204                 if ((do_pcibr_config_get(wptr, (win * 4), 4) &
1205                      PCI_BA_MEM_LOCATION) == PCI_BA_MEM_1MEG) {
1206  
1207                     /* allocate from 20-bit PCI space */
1208                     base = pcibr_bus_addr_alloc(pcibr_soft,
1209                                                 &pcibr_info->f_window[win],
1210                                                 PCIIO_SPACE_MEM,
1211                                                 0, size, align);
1212                     if (!base)
1213                         rc = ENOSPC;
1214                 } else {
1215                     /* allocate from 32-bit or 64-bit PCI space */
1216                     base = pcibr_bus_addr_alloc(pcibr_soft,
1217                                                 &pcibr_info->f_window[win],
1218                                                 PCIIO_SPACE_MEM32,
1219                                                 0, size, align);
1220                     if (!base) 
1221                         rc = ENOSPC;
1222                 }
1223                 break;
1224                 
1225             default:
1226                 base = 0;
1227                 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_BAR, pcibr_vhdl,
1228                             "pcibr_slot_addr_space_init: slot=%d, window %d "
1229                             "had bad space code %d\n", 
1230                             PCIBR_DEVICE_TO_SLOT(pcibr_soft,slot), win, space));
1231             }
1232             pcibr_info->f_window[win].w_base = base;
1233             do_pcibr_config_set(wptr, (win * 4), 4, base);
1234 
1235 #if defined(SUPPORT_PRINTING_R_FORMAT)
1236             if (pcibr_debug_mask & PCIBR_DEBUG_BAR) {
1237                 if (base >= size) {
1238                     sprintf(tmp_str,"pcibr_slot_addr_space_init: slot=%d, func="
1239                                     "%d, win %d is in %r[0x%x..0x%x], "
1240                                     "allocated by pcibr\n",
1241                                     PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), 
1242                                     func, win, space, space_desc, base, 
1243                                     base + size - 1);
1244                      PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_BAR, pcibr_vhdl, 
1245                                  "%s",tmp_str));
1246                 }
1247                 else {
1248                     sprintf(tmp_str,"pcibr_slot_addr_space_init: slot=%d, func="
1249                                     "%d, win %d, unable to alloc 0x%x in %r\n",
1250                                     PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), 
1251                                     func, win, size, space, space_desc);
1252                     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_BAR, pcibr_vhdl, 
1253                                 "%s",tmp_str));
1254                 }
1255             }
1256 #endif  /* SUPPORT_PRINTING_R_FORMAT */
1257         }                               /* next base */
1258 
1259         /*
1260          * Allocate space for the EXPANSION ROM
1261          */
1262         base = size = 0;
1263         {
1264             wptr = cfgw + PCI_EXPANSION_ROM / 4;
1265             do_pcibr_config_set(wptr, 0, 4, 0xFFFFF000);
1266             mask = do_pcibr_config_get(wptr, 0, 4);
1267             if (mask & 0xFFFFF000) {
1268                 size = mask & -mask;
1269                 base = pcibr_bus_addr_alloc(pcibr_soft,
1270                                             &pcibr_info->f_rwindow,
1271                                             PCIIO_SPACE_MEM32, 
1272                                             0, size, align);
1273                 if (!base)
1274                     rc = ENOSPC;
1275                 else {
1276                     do_pcibr_config_set(wptr, 0, 4, base);
1277                     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_BAR, pcibr_vhdl,
1278                                 "pcibr_slot_addr_space_init: slot=%d, func=%d, "
1279                                 "ROM in [0x%X..0x%X], allocated by pcibr\n",
1280                                 PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), 
1281                                 func, base, base + size - 1));
1282                 }
1283             }
1284         }
1285         pcibr_info->f_rbase = base;
1286         pcibr_info->f_rsize = size;
1287 
1288         /*
1289          * if necessary, update the board's
1290          * command register to enable decoding
1291          * in the windows we added.
1292          *
1293          * There are some bits we always want to
1294          * be sure are set.
1295          */
1296         pci_cfg_cmd_reg_add |= PCI_CMD_IO_SPACE;
1297 
1298         /*
1299          * The Adaptec 1160 FC Controller WAR #767995:
1300          * The part incorrectly ignores the upper 32 bits of a 64 bit
1301          * address when decoding references to its registers so to
1302          * keep it from responding to a bus cycle that it shouldn't
1303          * we only use I/O space to get at it's registers.  Don't
1304          * enable memory space accesses on that PCI device.
1305          */
1306         #define FCADP_VENDID 0x9004 /* Adaptec Vendor ID from fcadp.h */
1307         #define FCADP_DEVID 0x1160  /* Adaptec 1160 Device ID from fcadp.h */
1308 
1309         if ((pcibr_info->f_vendor != FCADP_VENDID) ||
1310             (pcibr_info->f_device != FCADP_DEVID))
1311             pci_cfg_cmd_reg_add |= PCI_CMD_MEM_SPACE;
1312 
1313         pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER;
1314 
1315         pci_cfg_cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4);
1316 
1317 #if PCI_FBBE    /* XXX- check here to see if dev can do fast-back-to-back */
1318         if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP))
1319             fast_back_to_back_enable = 0;
1320 #endif
1321         pci_cfg_cmd_reg &= 0xFFFF;
1322         if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg)
1323             do_pcibr_config_set(cfgw, PCI_CFG_COMMAND, 4, 
1324                                 pci_cfg_cmd_reg | pci_cfg_cmd_reg_add);
1325     }                           /* next func */
1326     return(rc);
1327 }
1328 
1329 /*
1330  * pcibr_slot_device_init
1331  *      Setup the device register in the bridge for this PCI slot.
1332  */
1333 
1334 int
1335 pcibr_slot_device_init(vertex_hdl_t pcibr_vhdl,
1336                        pciio_slot_t slot)
1337 {
1338     pcibr_soft_t         pcibr_soft;
1339     bridge_t            *bridge;
1340     bridgereg_t          devreg;
1341 
1342     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
1343 
1344     if (!pcibr_soft)
1345         return(EINVAL);
1346 
1347     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
1348         return(EINVAL);
1349 
1350     bridge = pcibr_soft->bs_base;
1351 
1352     /*
1353      * Adjustments to Device(x)
1354      * and init of bss_device shadow
1355      */
1356     devreg = bridge->b_device[slot].reg;
1357     devreg &= ~BRIDGE_DEV_PAGE_CHK_DIS;
1358 
1359     /*
1360      * PIC WAR. PV# 855271
1361      * Don't enable virtual channels in the PIC by default.
1362      * Can cause problems with 32-bit devices. (The bit is only intended
1363      * for 64-bit devices).  We set the bit in pcibr_try_set_device()
1364      * if we're 64-bit and requesting virtual channels.
1365      */
1366     if (IS_PIC_SOFT(pcibr_soft) && PCIBR_WAR_ENABLED(PV855271, pcibr_soft))
1367         devreg |= BRIDGE_DEV_COH;
1368     else
1369         devreg |= BRIDGE_DEV_COH | BRIDGE_DEV_VIRTUAL_EN;
1370     pcibr_soft->bs_slot[slot].bss_device = devreg;
1371     bridge->b_device[slot].reg = devreg;
1372 
1373 #ifdef PIC_LATER
1374     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DEVREG, pcibr_vhdl,
1375                 "pcibr_slot_device_init: Device(%d): %R\n",
1376                 slot, devreg, device_bits));
1377 #endif
1378     return(0);
1379 }
1380 
1381 /*
1382  * pcibr_slot_guest_info_init
1383  *      Setup the host/guest relations for a PCI slot.
1384  */
1385 int
1386 pcibr_slot_guest_info_init(vertex_hdl_t pcibr_vhdl,
1387                            pciio_slot_t slot)
1388 {
1389     pcibr_soft_t        pcibr_soft;
1390     pcibr_info_h        pcibr_infoh;
1391     pcibr_info_t        pcibr_info;
1392     pcibr_soft_slot_t   slotp;
1393 
1394     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
1395 
1396     if (!pcibr_soft)
1397         return(EINVAL);
1398 
1399     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
1400         return(EINVAL);
1401 
1402     slotp = &pcibr_soft->bs_slot[slot];
1403 
1404     /* create info and verticies for guest slots;
1405      * for compatibilitiy macros, create info
1406      * for even unpopulated slots (but do not
1407      * build verticies for them).
1408      */
1409     if (pcibr_soft->bs_slot[slot].bss_ninfo < 1) {
1410         NEWA(pcibr_infoh, 1);
1411         pcibr_soft->bs_slot[slot].bss_ninfo = 1;
1412         pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
1413 
1414         pcibr_info = pcibr_device_info_new
1415             (pcibr_soft, slot, PCIIO_FUNC_NONE,
1416              PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
1417 
1418         if (pcibr_soft->bs_slot[slot].has_host) {
1419             slotp->slot_conn = pciio_device_info_register
1420                 (pcibr_vhdl, &pcibr_info->f_c);
1421         }
1422     }
1423 
1424     /* generate host/guest relations
1425      */
1426     if (pcibr_soft->bs_slot[slot].has_host) {
1427         int  host = pcibr_soft->bs_slot[slot].host_slot;
1428         pcibr_soft_slot_t host_slotp = &pcibr_soft->bs_slot[host];
1429 
1430         hwgraph_edge_add(slotp->slot_conn,
1431                          host_slotp->slot_conn,
1432                          EDGE_LBL_HOST);
1433 
1434         /* XXX- only gives us one guest edge per
1435          * host. If/when we have a host with more than
1436          * one guest, we will need to figure out how
1437          * the host finds all its guests, and sorts
1438          * out which one is which.
1439          */
1440         hwgraph_edge_add(host_slotp->slot_conn,
1441                          slotp->slot_conn,
1442                          EDGE_LBL_GUEST);
1443     }
1444 
1445     return(0);
1446 }
1447 
1448 
1449 /*
1450  * pcibr_slot_call_device_attach
1451  *      This calls the associated driver attach routine for the PCI
1452  *      card in this slot.
1453  */
1454 int
1455 pcibr_slot_call_device_attach(vertex_hdl_t pcibr_vhdl,
1456                               pciio_slot_t slot,
1457                               int          drv_flags)
1458 {
1459     pcibr_soft_t        pcibr_soft;
1460     pcibr_info_h        pcibr_infoh;
1461     pcibr_info_t        pcibr_info;
1462     int                 func;
1463     vertex_hdl_t        xconn_vhdl, conn_vhdl;
1464 #ifdef PIC_LATER
1465     vertex_hdl_t        scsi_vhdl;
1466 #endif
1467     int                 nfunc;
1468     int                 error_func;
1469     int                 error_slot = 0;
1470     int                 error = ENODEV;
1471 #ifdef PIC_LATER
1472     int                 hwg_err;
1473 #endif
1474 
1475     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
1476 
1477     if (!pcibr_soft)
1478         return(EINVAL);
1479 
1480     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
1481         return(EINVAL);
1482 
1483     if (pcibr_soft->bs_slot[slot].has_host) {
1484         return(EPERM);
1485     }
1486     
1487     xconn_vhdl = pcibr_soft->bs_conn;
1488 
1489     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
1490     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
1491 
1492     for (func = 0; func < nfunc; ++func) {
1493 
1494         pcibr_info = pcibr_infoh[func];
1495         
1496         if (!pcibr_info)
1497             continue;
1498 
1499         if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
1500             continue;
1501 
1502         conn_vhdl = pcibr_info->f_vertex;
1503 
1504 
1505         error_func = pciio_device_attach(conn_vhdl, drv_flags);
1506 
1507 #ifdef PIC_LATER
1508         /*
1509          * Try to assign well-known SCSI controller numbers for hot-plug
1510          * insert
1511          */
1512         if (drv_flags) {
1513 
1514             hwg_err = hwgraph_path_lookup(conn_vhdl, EDGE_LBL_SCSI_CTLR "/0",
1515                                           &scsi_vhdl, NULL);
1516 
1517             if (hwg_err == GRAPH_SUCCESS)
1518                 scsi_ctlr_nums_add(baseio_pci_vhdl, scsi_vhdl);
1519 
1520             /* scsi_vhdl will be the final vertex in either the complete path
1521              * on success or a partial path on failure;  in either case,
1522              * unreference that vertex.
1523              */
1524             hwgraph_vertex_unref(scsi_vhdl);
1525 
1526             hwg_err = hwgraph_path_lookup(conn_vhdl, EDGE_LBL_SCSI_CTLR "/1",
1527                                           &scsi_vhdl, NULL);
1528 
1529             if (hwg_err == GRAPH_SUCCESS)
1530                 scsi_ctlr_nums_add(baseio_pci_vhdl, scsi_vhdl);
1531 
1532             /* scsi_vhdl will be the final vertex in either the complete path
1533              * on success or a partial path on failure;  in either case,
1534              * unreference that vertex.
1535              */
1536             hwgraph_vertex_unref(scsi_vhdl);
1537 
1538         }
1539 #endif /* PIC_LATER */
1540 
1541         pcibr_info->f_att_det_error = error_func;
1542 
1543         if (error_func)
1544             error_slot = error_func;
1545 
1546         error = error_slot;
1547 
1548     }                           /* next func */
1549 
1550     if (error) {
1551         if ((error != ENODEV) && (error != EUNATCH) && (error != EPERM)) {
1552             pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;
1553             pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_INCMPLT;
1554         }
1555     } else {
1556         pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;
1557         pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_CMPLT;
1558     }
1559         
1560     return(error);
1561 }
1562 
1563 /*
1564  * pcibr_slot_call_device_detach
1565  *      This calls the associated driver detach routine for the PCI
1566  *      card in this slot.
1567  */
1568 int
1569 pcibr_slot_call_device_detach(vertex_hdl_t pcibr_vhdl,
1570                               pciio_slot_t slot,
1571                               int          drv_flags)
1572 {
1573     pcibr_soft_t        pcibr_soft;
1574     pcibr_info_h        pcibr_infoh;
1575     pcibr_info_t        pcibr_info;
1576     int                 func;
1577     vertex_hdl_t        conn_vhdl = GRAPH_VERTEX_NONE;
1578     int                 nfunc;
1579     int                 error_func;
1580     int                 error_slot = 0;
1581     int                 error = ENODEV;
1582 
1583     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
1584 
1585     if (!pcibr_soft)
1586         return(EINVAL);
1587 
1588     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
1589         return(EINVAL);
1590 
1591     if (pcibr_soft->bs_slot[slot].has_host)
1592         return(EPERM);
1593 
1594     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
1595     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
1596 
1597     for (func = 0; func < nfunc; ++func) {
1598 
1599         pcibr_info = pcibr_infoh[func];
1600         
1601         if (!pcibr_info)
1602             continue;
1603 
1604         if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
1605             continue;
1606 
1607         if (IS_PCIX(pcibr_soft) && pcibr_info->f_pcix_cap) {
1608             int max_out;
1609 
1610             pcibr_soft->bs_pcix_num_funcs--;
1611             max_out = pcibr_info->f_pcix_cap->pcix_type0_status.max_out_split;
1612             pcibr_soft->bs_pcix_split_tot -= max_splittrans_to_numbuf[max_out];
1613         }
1614 
1615         conn_vhdl = pcibr_info->f_vertex;
1616 
1617         error_func = pciio_device_detach(conn_vhdl, drv_flags);
1618 
1619         pcibr_info->f_att_det_error = error_func;
1620 
1621         if (error_func)
1622             error_slot = error_func;
1623 
1624         error = error_slot;
1625 
1626     }                           /* next func */
1627 
1628 
1629     if (error) {
1630         if ((error != ENODEV) && (error != EUNATCH) && (error != EPERM)) {
1631             pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;
1632             pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_INCMPLT;
1633         }
1634     } else {
1635         if (conn_vhdl != GRAPH_VERTEX_NONE) 
1636             pcibr_device_unregister(conn_vhdl);
1637         pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;
1638         pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_CMPLT;
1639     }
1640         
1641     return(error);
1642 }
1643 
1644 /*
1645  * pcibr_slot_attach
1646  *      This is a place holder routine to keep track of all the
1647  *      slot-specific initialization that needs to be done.
1648  *      This is usually called when we want to initialize a new
1649  *      PCI card on the bus.
1650  */
1651 int
1652 pcibr_slot_attach(vertex_hdl_t pcibr_vhdl,
1653                   pciio_slot_t slot,
1654                   int          drv_flags,
1655                   char        *l1_msg,
1656                   int         *sub_errorp)
1657 {
1658     pcibr_soft_t  pcibr_soft = pcibr_soft_get(pcibr_vhdl);
1659 #ifdef PIC_LATER
1660     timespec_t    ts;
1661 #endif
1662     int           error;
1663 
1664     /* Do not allow a multi-function card to be hot-plug inserted */
1665     if (pcibr_soft->bs_slot[slot].bss_ninfo > 1) {
1666         if (sub_errorp)
1667             *sub_errorp = EPERM;
1668         return(PCI_MULTI_FUNC_ERR);
1669     }
1670 
1671     /* Call the device attach */
1672     error = pcibr_slot_call_device_attach(pcibr_vhdl, slot, drv_flags);
1673     if (error) {
1674         if (sub_errorp)
1675             *sub_errorp = error;
1676         if (error == EUNATCH)
1677             return(PCI_NO_DRIVER);
1678         else
1679             return(PCI_SLOT_DRV_ATTACH_ERR);
1680     }
1681 
1682     return(0);
1683 }
1684 
1685 /*
1686  * pcibr_slot_detach
1687  *      This is a place holder routine to keep track of all the
1688  *      slot-specific freeing that needs to be done.
1689  */
1690 int
1691 pcibr_slot_detach(vertex_hdl_t pcibr_vhdl,
1692                   pciio_slot_t slot,
1693                   int          drv_flags,
1694                   char        *l1_msg,
1695                   int         *sub_errorp)
1696 {
1697     pcibr_soft_t  pcibr_soft = pcibr_soft_get(pcibr_vhdl);
1698     int           error;
1699     
1700     /* Call the device detach function */
1701     error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags));
1702     if (error) {
1703         if (sub_errorp)
1704             *sub_errorp = error;       
1705         return(PCI_SLOT_DRV_DETACH_ERR);
1706     }
1707 
1708     /* Recalculate the RBARs for all the devices on the bus since we've
1709      * just freed some up and some of the devices could use them.
1710      */
1711     if (IS_PCIX(pcibr_soft)) {
1712         int tmp_slot;
1713 
1714         pcibr_soft->bs_pcix_rbar_inuse = 0;
1715         pcibr_soft->bs_pcix_rbar_avail = NUM_RBAR;
1716         pcibr_soft->bs_pcix_rbar_percent_allowed = 
1717                                         pcibr_pcix_rbars_calc(pcibr_soft);
1718 
1719         for (tmp_slot = pcibr_soft->bs_min_slot;
1720                         tmp_slot < PCIBR_NUM_SLOTS(pcibr_soft); ++tmp_slot)
1721             (void)pcibr_slot_pcix_rbar_init(pcibr_soft, tmp_slot);
1722     }
1723 
1724     return (0);
1725 
1726 }
1727 
1728 /*
1729  * pcibr_probe_slot_pic: read a config space word
1730  * while trapping any errors; return zero if
1731  * all went OK, or nonzero if there was an error.
1732  * The value read, if any, is passed back
1733  * through the valp parameter.
1734  */
1735 static int
1736 pcibr_probe_slot_pic(bridge_t *bridge,
1737                  cfg_p cfg,
1738                  unsigned *valp)
1739 {
1740         int rv;
1741         picreg_t p_old_enable = (picreg_t)0, p_new_enable;
1742         extern int badaddr_val(volatile void *, int, volatile void *);
1743 
1744         p_old_enable = bridge->p_int_enable_64;
1745         p_new_enable = p_old_enable & ~(BRIDGE_IMR_PCI_MST_TIMEOUT | PIC_ISR_PCIX_MTOUT);
1746         bridge->p_int_enable_64 = p_new_enable;
1747 
1748         if (bridge->p_err_int_view_64 & (BRIDGE_ISR_PCI_MST_TIMEOUT | PIC_ISR_PCIX_MTOUT))
1749                 bridge->p_int_rst_stat_64 = BRIDGE_IRR_MULTI_CLR;
1750 
1751         if (bridge->p_int_status_64 & (BRIDGE_IRR_PCI_GRP | PIC_PCIX_GRP_CLR)) {
1752                 bridge->p_int_rst_stat_64 = (BRIDGE_IRR_PCI_GRP_CLR | PIC_PCIX_GRP_CLR);
1753                 (void) bridge->b_wid_tflush;    /* flushbus */
1754         }
1755         rv = badaddr_val((void *) cfg, 4, valp);
1756         if (bridge->p_err_int_view_64 & (BRIDGE_ISR_PCI_MST_TIMEOUT | PIC_ISR_PCIX_MTOUT)) {
1757                 bridge->p_int_rst_stat_64 = BRIDGE_IRR_MULTI_CLR;
1758                 rv = 1;         /* unoccupied slot */
1759         }
1760         bridge->p_int_enable_64 = p_old_enable;
1761         bridge->b_wid_tflush;           /* wait until Bridge PIO complete */
1762         return(rv);
1763 }
1764 
1765 /*
1766  * pcibr_probe_slot: read a config space word
1767  * while trapping any errors; return zero if
1768  * all went OK, or nonzero if there was an error.
1769  * The value read, if any, is passed back
1770  * through the valp parameter.
1771  */
1772 static int
1773 pcibr_probe_slot(bridge_t *bridge,
1774                  cfg_p cfg,
1775                  unsigned *valp)
1776 {
1777     return(pcibr_probe_slot_pic(bridge, cfg, valp));
1778 }
1779 
1780 
1781 void
1782 pcibr_device_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot)
1783 {
1784     pcibr_soft_t        pcibr_soft = pcibr_soft_get(pcibr_vhdl);
1785     pcibr_info_t        pcibr_info;
1786     pciio_function_t    func;
1787     pcibr_soft_slot_t   slotp = &pcibr_soft->bs_slot[slot];
1788     bridge_t           *bridge = pcibr_soft->bs_base; 
1789     cfg_p               cfgw;
1790     int                 nfunc = slotp->bss_ninfo;
1791     int                 bar;
1792     int                 devio_index;
1793     int                 s;
1794     unsigned            cmd_reg;
1795 
1796 
1797     for (func = 0; func < nfunc; func++) {
1798         pcibr_info = slotp->bss_infos[func];
1799 
1800         if (!pcibr_info) 
1801             continue;
1802 
1803         s = pcibr_lock(pcibr_soft);
1804 
1805         /* Disable memory and I/O BARs */
1806         cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0);
1807         cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4);
1808         cmd_reg &= (PCI_CMD_MEM_SPACE | PCI_CMD_IO_SPACE);
1809         do_pcibr_config_set(cfgw, PCI_CFG_COMMAND, 4, cmd_reg);
1810 
1811         for (bar = 0; bar < PCI_CFG_BASE_ADDRS; bar++) {
1812             if (pcibr_info->f_window[bar].w_space == PCIIO_SPACE_NONE)
1813                 continue;
1814 
1815             /* Free the PCI bus space */
1816             pciibr_bus_addr_free(pcibr_soft, &pcibr_info->f_window[bar]);
1817 
1818             /* Get index of the DevIO(x) register used to access this BAR */
1819             devio_index = pcibr_info->f_window[bar].w_devio_index;
1820 
1821  
1822             /* On last use, clear the DevIO(x) used to access this BAR */
1823             if (! --pcibr_soft->bs_slot[devio_index].bss_devio.bssd_ref_cnt) {
1824                pcibr_soft->bs_slot[devio_index].bss_devio.bssd_space =
1825                                                        PCIIO_SPACE_NONE; 
1826                pcibr_soft->bs_slot[devio_index].bss_devio.bssd_base =
1827                                                        PCIBR_D32_BASE_UNSET;
1828                pcibr_soft->bs_slot[devio_index].bss_device = 0;
1829             }
1830         }
1831 
1832         /* Free the Expansion ROM PCI bus space */
1833         if(pcibr_info->f_rbase && pcibr_info->f_rsize) {
1834             pciibr_bus_addr_free(pcibr_soft, &pcibr_info->f_rwindow);
1835         }
1836 
1837         pcibr_unlock(pcibr_soft, s);
1838 
1839         slotp->bss_infos[func] = 0;
1840         pciio_device_info_unregister(pcibr_vhdl, &pcibr_info->f_c);
1841         pciio_device_info_free(&pcibr_info->f_c);
1842 
1843         DEL(pcibr_info);
1844     }
1845 
1846     /* Reset the mapping usage counters */
1847     slotp->bss_pmu_uctr = 0;
1848     slotp->bss_d32_uctr = 0;
1849     slotp->bss_d64_uctr = 0;
1850 
1851     /* Clear the Direct translation info */
1852     slotp->bss_d64_base = PCIBR_D64_BASE_UNSET;
1853     slotp->bss_d64_flags = 0;
1854     slotp->bss_d32_base = PCIBR_D32_BASE_UNSET;
1855     slotp->bss_d32_flags = 0;
1856 
1857     /* Clear out shadow info necessary for the external SSRAM workaround */
1858     slotp->bss_ext_ates_active = ATOMIC_INIT(0);
1859     slotp->bss_cmd_pointer = 0;
1860     slotp->bss_cmd_shadow = 0;
1861 
1862 }
1863 
1864 
1865 iopaddr_t
1866 pcibr_bus_addr_alloc(pcibr_soft_t pcibr_soft, pciio_win_info_t win_info_p,
1867                      pciio_space_t space, int start, int size, int align)
1868 {
1869     pciio_win_map_t win_map_p;
1870     struct resource *root_resource = NULL;
1871     iopaddr_t iopaddr = 0;
1872 
1873     switch (space) {
1874 
1875         case PCIIO_SPACE_IO:
1876             win_map_p = &pcibr_soft->bs_io_win_map;
1877             root_resource = &pcibr_soft->bs_io_win_root_resource;
1878             break;
1879 
1880         case PCIIO_SPACE_MEM:
1881             win_map_p = &pcibr_soft->bs_swin_map;
1882             root_resource = &pcibr_soft->bs_swin_root_resource;
1883             break;
1884 
1885         case PCIIO_SPACE_MEM32:
1886             win_map_p = &pcibr_soft->bs_mem_win_map;
1887             root_resource = &pcibr_soft->bs_mem_win_root_resource;
1888             break;
1889 
1890         default:
1891             return 0;
1892 
1893     }
1894     iopaddr = pciio_device_win_alloc(root_resource,
1895                                   win_info_p
1896                                   ? &win_info_p->w_win_alloc
1897                                   : NULL,
1898                                   start, size, align);
1899     return(iopaddr);
1900 }
1901 
1902 
1903 void
1904 pciibr_bus_addr_free(pcibr_soft_t pcibr_soft, pciio_win_info_t win_info_p)
1905 {
1906         pciio_device_win_free(&win_info_p->w_win_alloc);
1907 }
1908 
1909 /*
1910  * given a vertex_hdl to the pcibr_vhdl, return the brick's bus number
1911  * associated with that vertex_hdl.  The true mapping happens from the
1912  * io_brick_tab[] array defined in ml/SN/iograph.c
1913  */
1914 int
1915 pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl) 
1916 {
1917     pcibr_soft_t        pcibr_soft = pcibr_soft_get(pcibr_vhdl);
1918     xwidgetnum_t        widget = pcibr_soft->bs_xid;
1919     int                 bricktype = pcibr_soft->bs_bricktype;
1920     int                 bus = pcibr_soft->bs_busnum;
1921     
1922     /* 
1923      * For PIC there are 2 busses per widget and pcibr_soft->bs_busnum
1924      * will be 0 or 1.  For [X]BRIDGE there is 1 bus per widget and 
1925      * pcibr_soft->bs_busnum will always be zero.  So we add bs_busnum
1926      * to what io_brick_map_widget returns to get the bus number.
1927      */
1928     if ((bus += io_brick_map_widget(bricktype, widget)) > 0) {
1929         return bus;
1930     } else {
1931         return 0;
1932     }
1933 }
1934 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp