pcibr_slot.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:48k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *
  3.  * This file is subject to the terms and conditions of the GNU General Public
  4.  * License.  See the file "COPYING" in the main directory of this archive
  5.  * for more details.
  6.  *
  7.  * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
  8.  */
  9. #include <linux/types.h>
  10. #include <linux/slab.h>
  11. #include <linux/module.h>
  12. #include <asm/sn/sgi.h>
  13. #include <asm/sn/sn_cpuid.h>
  14. #include <asm/sn/addrs.h>
  15. #include <asm/sn/arch.h>
  16. #include <asm/sn/iograph.h>
  17. #include <asm/sn/invent.h>
  18. #include <asm/sn/hcl.h>
  19. #include <asm/sn/labelcl.h>
  20. #include <asm/sn/xtalk/xwidget.h>
  21. #include <asm/sn/pci/bridge.h>
  22. #include <asm/sn/pci/pciio.h>
  23. #include <asm/sn/pci/pcibr.h>
  24. #include <asm/sn/pci/pcibr_private.h>
  25. #include <asm/sn/pci/pci_defs.h>
  26. #include <asm/sn/prio.h>
  27. #include <asm/sn/xtalk/xbow.h>
  28. #include <asm/sn/ioc3.h>
  29. #include <asm/sn/eeprom.h>
  30. #include <asm/sn/io.h>
  31. #include <asm/sn/sn_private.h>
  32. extern pcibr_info_t     pcibr_info_get(devfs_handle_t);
  33. extern int              pcibr_widget_to_bus(int);
  34. 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);
  35. extern void             pcibr_freeblock_sub(iopaddr_t *, iopaddr_t *, iopaddr_t, size_t);
  36. extern int pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
  37. #if 0
  38. int pcibr_slot_reset(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
  39. #endif
  40. int pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
  41. int pcibr_slot_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
  42. int pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
  43. int pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
  44. int pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
  45. int pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
  46.  pciio_slot_t slot, int drv_flags);
  47. int pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
  48.  pciio_slot_t slot, int drv_flags);
  49. int pcibr_slot_detach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot, int drv_flags);
  50. int pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
  51. int pcibr_probe_slot(bridge_t *, cfg_p, unsigned int *);
  52. void  pcibr_device_info_free(devfs_handle_t, pciio_slot_t);
  53. extern uint64_t  do_pcibr_config_get(cfg_p, unsigned, unsigned);
  54. #ifdef LATER
  55. int pcibr_slot_attach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot,
  56.                 int drv_flags, char *l1_msg, int *sub_errorp);
  57. int pcibr_slot_pwr(devfs_handle_t, pciio_slot_t, int, char *);
  58. int pcibr_slot_startup(devfs_handle_t, pcibr_slot_req_t);
  59. int pcibr_slot_shutdown(devfs_handle_t, pcibr_slot_req_t);
  60. void pcibr_slot_func_info_return(pcibr_info_h pcibr_infoh, int func,
  61.                  pcibr_slot_func_info_resp_t funcp);
  62. int pcibr_slot_info_return(pcibr_soft_t pcibr_soft, pciio_slot_t slot,
  63.                  pcibr_slot_info_resp_t respp);
  64. int pcibr_slot_query(devfs_handle_t, pcibr_slot_req_t);
  65. #endif /* LATER */
  66. extern devfs_handle_t baseio_pci_vhdl;
  67. int scsi_ctlr_nums_add(devfs_handle_t, devfs_handle_t);
  68. /* For now .... */
  69. /*
  70.  * PCI Hot-Plug Capability Flags
  71.  */
  72. #define D_PCI_HOT_PLUG_ATTACH  0x200  /* Driver supports PCI hot-plug attach */
  73. #define D_PCI_HOT_PLUG_DETACH  0x400  /* Driver supports PCI hot-plug detach */
  74. /*==========================================================================
  75.  * BRIDGE PCI SLOT RELATED IOCTLs
  76.  */
  77. #ifdef LATER
  78. /*
  79.  * pcibr_slot_startup
  80.  * Software start-up the PCI slot.
  81.  */
  82. int
  83. pcibr_slot_startup(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
  84. {
  85.     pcibr_soft_t                   pcibr_soft = pcibr_soft_get(pcibr_vhdl);
  86.     pciio_slot_t                   slot = reqp->req_slot;
  87.     int                            error = 0;
  88.     char                           l1_msg[BRL1_QSIZE+1];
  89.     struct pcibr_slot_up_resp_s    tmp_up_resp;
  90.     /* Make sure that we are dealing with a bridge device vertex */
  91.     if (!pcibr_soft) {
  92.         return(PCI_NOT_A_BRIDGE);
  93.     }
  94.     /* Do not allow start-up of a slot in a shoehorn */
  95.     if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
  96.        return(PCI_SLOT_IN_SHOEHORN);
  97.     }
  98.  
  99.     /* Check for the valid slot */
  100.     if (!PCIBR_VALID_SLOT(slot))
  101.         return(PCI_NOT_A_SLOT);
  102.     /* Acquire update access to the bus */
  103.     mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);
  104.     if (pcibr_soft->bs_slot[slot].slot_status & SLOT_STARTUP_CMPLT) {
  105.         error = PCI_SLOT_ALREADY_UP;
  106.         goto startup_unlock;
  107.     }
  108.     error = pcibr_slot_attach(pcibr_vhdl, slot, D_PCI_HOT_PLUG_ATTACH,
  109.                               l1_msg, &tmp_up_resp.resp_sub_errno);
  110.     strncpy(tmp_up_resp.resp_l1_msg, l1_msg, L1_QSIZE);
  111.     tmp_up_resp.resp_l1_msg[L1_QSIZE] = '';
  112.     if (COPYOUT(&tmp_up_resp, reqp->req_respp.up, reqp->req_size)) {
  113.         return(EFAULT);
  114.     }
  115.     startup_unlock:
  116.     /* Release the bus lock */
  117.     mrunlock(pcibr_soft->bs_bus_lock);
  118.     return(error);
  119. }
  120. /*
  121.  * pcibr_slot_shutdown
  122.  * Software shut-down the PCI slot
  123.  */
  124. int
  125. pcibr_slot_shutdown(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
  126. {
  127.     pcibr_soft_t                   pcibr_soft = pcibr_soft_get(pcibr_vhdl);
  128.     bridge_t                      *bridge;
  129.     pciio_slot_t                   slot = reqp->req_slot;
  130.     int                            error = 0;
  131.     char                           l1_msg[BRL1_QSIZE+1];
  132.     struct pcibr_slot_down_resp_s  tmp_down_resp;
  133.     pciio_slot_t                   tmp_slot;
  134.     /* Make sure that we are dealing with a bridge device vertex */
  135.     if (!pcibr_soft) {
  136.         return(PCI_NOT_A_BRIDGE);
  137.     }
  138.     bridge = pcibr_soft->bs_base;
  139.     /* Check for valid slot */
  140.     if (!PCIBR_VALID_SLOT(slot))
  141.         return(PCI_NOT_A_SLOT);
  142.     /* Do not allow shut-down of a slot in a shoehorn */
  143.     if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
  144.        return(PCI_SLOT_IN_SHOEHORN);
  145.     }
  146.     /* Acquire update access to the bus */
  147.     mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);
  148.     if ((pcibr_soft->bs_slot[slot].slot_status & SLOT_SHUTDOWN_CMPLT) ||
  149.         ((pcibr_soft->bs_slot[slot].slot_status & SLOT_STATUS_MASK) == 0)) {
  150.         error = PCI_SLOT_ALREADY_DOWN;
  151.         /*
  152.          * RJR - Should we invoke an L1 slot power-down command just in case
  153.          *       a previous shut-down failed to power-down the slot?
  154.          */
  155.         goto shutdown_unlock;
  156.     }
  157.     /* Do not allow the last 33 MHz card to be removed */
  158.     if ((bridge->b_wid_control & BRIDGE_CTRL_BUS_SPEED_MASK) ==
  159.          BRIDGE_CTRL_BUS_SPEED_33) {
  160.         for (tmp_slot = pcibr_soft->bs_first_slot;
  161.              tmp_slot <= pcibr_soft->bs_last_slot; tmp_slot++)
  162.             if (tmp_slot != slot)
  163.                 if (pcibr_soft->bs_slot[tmp_slot].slot_status & SLOT_POWER_UP) {
  164.                     error++;
  165.                     break;
  166.                 }
  167.         if (!error) {
  168.             error = PCI_EMPTY_33MHZ;
  169.             goto shutdown_unlock;
  170.         }
  171.     }
  172.     error = pcibr_slot_detach(pcibr_vhdl, slot, D_PCI_HOT_PLUG_DETACH,
  173.                               l1_msg, &tmp_down_resp.resp_sub_errno);
  174.     strncpy(tmp_down_resp.resp_l1_msg, l1_msg, L1_QSIZE);
  175.     tmp_down_resp.resp_l1_msg[L1_QSIZE] = '';
  176.     if (COPYOUT(&tmp_down_resp, reqp->req_respp.down, reqp->req_size)) {
  177.         return(EFAULT);
  178.     }
  179.     shutdown_unlock:
  180.     /* Release the bus lock */
  181.     mrunlock(pcibr_soft->bs_bus_lock);
  182.     return(error);
  183. }
  184. char *pci_space_name[] = {"NONE", 
  185.   "ROM",
  186.   "IO",
  187.   "",
  188.   "MEM",
  189.   "MEM32",
  190.   "MEM64",
  191.   "CFG",
  192.   "WIN0",
  193.   "WIN1",
  194.   "WIN2",
  195.   "WIN3",
  196.   "WIN4",
  197.   "WIN5",
  198.   "",
  199.   "BAD"};
  200. void
  201. pcibr_slot_func_info_return(pcibr_info_h pcibr_infoh,
  202.                             int func,
  203.                             pcibr_slot_func_info_resp_t funcp)
  204. {
  205.     pcibr_info_t                 pcibr_info = pcibr_infoh[func];
  206.     int                          win;
  207.     funcp->resp_f_status = 0;
  208.     if (!pcibr_info) {
  209.         return;
  210.     }
  211.     funcp->resp_f_status |= FUNC_IS_VALID;
  212.     sprintf(funcp->resp_f_slot_name, "%v", pcibr_info->f_vertex);
  213.     if(is_sys_critical_vertex(pcibr_info->f_vertex)) {
  214.         funcp->resp_f_status |= FUNC_IS_SYS_CRITICAL;
  215.     }
  216.     funcp->resp_f_bus = pcibr_info->f_bus;
  217.     funcp->resp_f_slot = pcibr_info->f_slot;
  218.     funcp->resp_f_func = pcibr_info->f_func;
  219.     sprintf(funcp->resp_f_master_name, "%v", pcibr_info->f_master);
  220.     funcp->resp_f_pops = pcibr_info->f_pops;
  221.     funcp->resp_f_efunc = pcibr_info->f_efunc;
  222.     funcp->resp_f_einfo = pcibr_info->f_einfo;
  223.     funcp->resp_f_vendor = pcibr_info->f_vendor;
  224.     funcp->resp_f_device = pcibr_info->f_device;
  225.     for(win = 0 ; win < 6 ; win++) {
  226.         funcp->resp_f_window[win].resp_w_base =
  227.                                   pcibr_info->f_window[win].w_base;
  228.         funcp->resp_f_window[win].resp_w_size =
  229.                                   pcibr_info->f_window[win].w_size;
  230.         sprintf(funcp->resp_f_window[win].resp_w_space,
  231.                 "%s",
  232.                 pci_space_name[pcibr_info->f_window[win].w_space]);
  233.     }
  234.     funcp->resp_f_rbase = pcibr_info->f_rbase;
  235.     funcp->resp_f_rsize = pcibr_info->f_rsize;
  236.     for (win = 0 ; win < 4; win++) {
  237.         funcp->resp_f_ibit[win] = pcibr_info->f_ibit[win];
  238.     }
  239.     funcp->resp_f_att_det_error = pcibr_info->f_att_det_error;
  240. }
  241. int
  242. pcibr_slot_info_return(pcibr_soft_t             pcibr_soft,
  243.                        pciio_slot_t             slot,
  244.                        pcibr_slot_info_resp_t   respp)
  245. {
  246.     pcibr_soft_slot_t            pss;
  247.     int                          func;
  248.     bridge_t                    *bridge = pcibr_soft->bs_base;
  249.     reg_p                        b_respp;
  250.     pcibr_slot_info_resp_t       slotp;
  251.     pcibr_slot_func_info_resp_t  funcp;
  252.     slotp = kmem_zalloc(sizeof(*slotp), KM_SLEEP);
  253.     if (slotp == NULL) {
  254.         return(ENOMEM);
  255.     }
  256.     pss = &pcibr_soft->bs_slot[slot];
  257.     slotp->resp_has_host = pss->has_host;
  258.     slotp->resp_host_slot = pss->host_slot;
  259.     sprintf(slotp->resp_slot_conn_name, "%v", pss->slot_conn);
  260.     slotp->resp_slot_status = pss->slot_status;
  261.     slotp->resp_l1_bus_num = io_path_map_widget(pcibr_soft->bs_vhdl);
  262.     if (is_sys_critical_vertex(pss->slot_conn)) {
  263.         slotp->resp_slot_status |= SLOT_IS_SYS_CRITICAL;
  264.     }
  265.     slotp->resp_bss_ninfo = pss->bss_ninfo;
  266.     for (func = 0; func < pss->bss_ninfo; func++) {
  267.         funcp = &(slotp->resp_func[func]);
  268.         pcibr_slot_func_info_return(pss->bss_infos, func, funcp);
  269.     }
  270.     sprintf(slotp->resp_bss_devio_bssd_space, "%s",
  271.             pci_space_name[pss->bss_devio.bssd_space]);
  272.     slotp->resp_bss_devio_bssd_base = pss->bss_devio.bssd_base;
  273.     slotp->resp_bss_device = pss->bss_device;
  274.     slotp->resp_bss_pmu_uctr = pss->bss_pmu_uctr;
  275.     slotp->resp_bss_d32_uctr = pss->bss_d32_uctr;
  276.     slotp->resp_bss_d64_uctr = pss->bss_d64_uctr;
  277.     slotp->resp_bss_d64_base = pss->bss_d64_base;
  278.     slotp->resp_bss_d64_flags = pss->bss_d64_flags;
  279.     slotp->resp_bss_d32_base = pss->bss_d32_base;
  280.     slotp->resp_bss_d32_flags = pss->bss_d32_flags;
  281.     slotp->resp_bss_ext_ates_active = pss->bss_ext_ates_active;
  282.     slotp->resp_bss_cmd_pointer = pss->bss_cmd_pointer;
  283.     slotp->resp_bss_cmd_shadow = pss->bss_cmd_shadow;
  284.     slotp->resp_bs_rrb_valid = pcibr_soft->bs_rrb_valid[slot];
  285.     slotp->resp_bs_rrb_valid_v = pcibr_soft->bs_rrb_valid[slot +
  286.                                                       PCIBR_RRB_SLOT_VIRTUAL];
  287.     slotp->resp_bs_rrb_res = pcibr_soft->bs_rrb_res[slot];
  288.     if (slot & 1) {
  289.         b_respp = &bridge->b_odd_resp;
  290.     } else {
  291.         b_respp = &bridge->b_even_resp;
  292.     }
  293.     slotp->resp_b_resp = *b_respp;
  294.     slotp->resp_b_wid_control = bridge->b_wid_control;
  295.     slotp->resp_b_int_device = bridge->b_int_device;
  296.     slotp->resp_b_int_enable = bridge->b_int_enable;
  297.     slotp->resp_b_int_host = bridge->b_int_addr[slot].addr;
  298.     if (COPYOUT(slotp, respp, sizeof(*respp))) {
  299.         return(EFAULT);
  300.     }
  301.     kmem_free(slotp, sizeof(*slotp));
  302.     return(0);
  303. }
  304. /*
  305.  * pcibr_slot_query
  306.  * Return information about the PCI slot maintained by the infrastructure.
  307.  * Information is requested in the request structure.
  308.  *
  309.  *      Information returned in the response structure:
  310.  * Slot hwgraph name
  311.  * Vendor/Device info
  312.  * Base register info
  313.  * Interrupt mapping from device pins to the bridge pins
  314.  * Devio register
  315.  * Software RRB info
  316.  * RRB register info
  317.  * Host/Gues info
  318.  * PCI Bus #,slot #, function #
  319.  * Slot provider hwgraph name
  320.  * Provider Functions
  321.  * Error handler
  322.  * DMA mapping usage counters
  323.  * DMA direct translation info
  324.  * External SSRAM workaround info
  325.  */
  326. int
  327. pcibr_slot_query(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
  328. {
  329.     pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
  330.     pciio_slot_t            slot = reqp->req_slot;
  331.     pciio_slot_t            tmp_slot;
  332.     pcibr_slot_info_resp_t  respp = reqp->req_respp.query;
  333.     int                     size = reqp->req_size;
  334.     int                     error;
  335.     /* Make sure that we are dealing with a bridge device vertex */
  336.     if (!pcibr_soft) {
  337.         return(PCI_NOT_A_BRIDGE);
  338.     }
  339.     /* Make sure that we have a valid PCI slot number or PCIIO_SLOT_NONE */
  340.     if ((!PCIBR_VALID_SLOT(slot)) && (slot != PCIIO_SLOT_NONE)) {
  341.         return(PCI_NOT_A_SLOT);
  342.     }
  343.     /* Do not allow a query of a slot in a shoehorn */
  344.     if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
  345.        return(PCI_SLOT_IN_SHOEHORN);
  346.     }
  347.     /* Return information for the requested PCI slot */
  348.     if (slot != PCIIO_SLOT_NONE) {
  349.         if (size < sizeof(*respp)) {
  350.             return(PCI_RESP_AREA_TOO_SMALL);
  351.         }
  352.         /* Acquire read access to the bus */
  353.         mrlock(pcibr_soft->bs_bus_lock, MR_ACCESS, PZERO);
  354.         error = pcibr_slot_info_return(pcibr_soft, slot, respp);
  355.         /* Release the bus lock */
  356.         mrunlock(pcibr_soft->bs_bus_lock);
  357.         return(error);
  358.     }
  359.     /* Return information for all the slots */
  360.     for (tmp_slot = 0; tmp_slot < 8; tmp_slot++) {
  361.         if (size < sizeof(*respp)) {
  362.             return(PCI_RESP_AREA_TOO_SMALL);
  363.         }
  364.         /* Acquire read access to the bus */
  365.         mrlock(pcibr_soft->bs_bus_lock, MR_ACCESS, PZERO);
  366.         error = pcibr_slot_info_return(pcibr_soft, tmp_slot, respp);
  367.         /* Release the bus lock */
  368.         mrunlock(pcibr_soft->bs_bus_lock);
  369.         if (error) {
  370.             return(error);
  371.         }
  372.         ++respp;
  373.         size -= sizeof(*respp);
  374.     }
  375.     return(error);
  376. }
  377. #endif /* LATER */
  378. /* FIXME: there should be a better way to do this.
  379.  * pcibr_attach() needs PCI_ADDR_SPACE_LIMITS_STORE
  380.  */
  381. /* 
  382.  * PCI_ADDR_SPACE_LIMITS_LOAD
  383.  * Gets the current values of 
  384.  * pci io base, 
  385.  * pci io last,
  386.  * pci low memory base,
  387.  * pci low memory last,
  388.  * pci high memory base,
  389.  *  pci high memory last
  390.  */
  391. #define PCI_ADDR_SPACE_LIMITS_LOAD()
  392.     pci_io_fb = pcibr_soft->bs_spinfo.pci_io_base;
  393.     pci_io_fl = pcibr_soft->bs_spinfo.pci_io_last;
  394.     pci_lo_fb = pcibr_soft->bs_spinfo.pci_swin_base;
  395.     pci_lo_fl = pcibr_soft->bs_spinfo.pci_swin_last;
  396.     pci_hi_fb = pcibr_soft->bs_spinfo.pci_mem_base;
  397.     pci_hi_fl = pcibr_soft->bs_spinfo.pci_mem_last;
  398. /*
  399.  * PCI_ADDR_SPACE_LIMITS_STORE
  400.  * Sets the current values of
  401.  * pci io base, 
  402.  * pci io last,
  403.  * pci low memory base,
  404.  * pci low memory last,
  405.  * pci high memory base,
  406.  *  pci high memory last
  407.  */
  408. #define PCI_ADDR_SPACE_LIMITS_STORE()
  409.     pcibr_soft->bs_spinfo.pci_io_base = pci_io_fb;
  410.     pcibr_soft->bs_spinfo.pci_io_last = pci_io_fl;
  411.     pcibr_soft->bs_spinfo.pci_swin_base = pci_lo_fb;
  412.     pcibr_soft->bs_spinfo.pci_swin_last = pci_lo_fl;
  413.     pcibr_soft->bs_spinfo.pci_mem_base = pci_hi_fb;
  414.     pcibr_soft->bs_spinfo.pci_mem_last = pci_hi_fl;
  415. #define PCI_ADDR_SPACE_LIMITS_PRINT()
  416.     printf("+++++++++++++++++++++++n"
  417.    "IO base 0x%x last 0x%xn"
  418.    "SWIN base 0x%x last 0x%xn"
  419.    "MEM base 0x%x last 0x%xn"
  420.    "+++++++++++++++++++++++n",
  421.    pcibr_soft->bs_spinfo.pci_io_base,
  422.    pcibr_soft->bs_spinfo.pci_io_last,
  423.    pcibr_soft->bs_spinfo.pci_swin_base,
  424.    pcibr_soft->bs_spinfo.pci_swin_last,
  425.    pcibr_soft->bs_spinfo.pci_mem_base,
  426.    pcibr_soft->bs_spinfo.pci_mem_last);
  427. /*
  428.  * pcibr_slot_info_init
  429.  * Probe for this slot and see if it is populated.
  430.  * If it is populated initialize the generic PCI infrastructural
  431.  *  information associated with this particular PCI device.
  432.  */
  433. int
  434. pcibr_slot_info_init(devfs_handle_t  pcibr_vhdl,
  435.      pciio_slot_t  slot)
  436. {
  437.     pcibr_soft_t     pcibr_soft;
  438.     pcibr_info_h     pcibr_infoh;
  439.     pcibr_info_t     pcibr_info;
  440.     bridge_t    *bridge;
  441.     cfg_p                   cfgw;
  442.     unsigned                idword;
  443.     unsigned                pfail;
  444.     unsigned                idwords[8];
  445.     pciio_vendor_id_t       vendor;
  446.     pciio_device_id_t       device;
  447.     unsigned                htype;
  448.     cfg_p                   wptr;
  449.     int                     win;
  450.     pciio_space_t           space;
  451.     iopaddr_t     pci_io_fb, pci_io_fl;
  452.     iopaddr_t     pci_lo_fb,  pci_lo_fl;
  453.     iopaddr_t     pci_hi_fb,  pci_hi_fl;
  454.     int     nfunc;
  455.     pciio_function_t     rfunc;
  456.     int     func;
  457.     devfs_handle_t     conn_vhdl;
  458.     pcibr_soft_slot_t     slotp;
  459.     
  460.     /* Get the basic software information required to proceed */
  461.     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
  462.     if (!pcibr_soft)
  463. return(EINVAL);
  464.     bridge = pcibr_soft->bs_base;
  465.     if (!PCIBR_VALID_SLOT(slot))
  466. return(EINVAL);
  467.     /* If we have a host slot (eg:- IOC3 has 2 PCI slots and the initialization
  468.      * is done by the host slot then we are done.
  469.      */
  470.     if (pcibr_soft->bs_slot[slot].has_host) {
  471. return(0);    
  472.     }
  473.     /* Check for a slot with any system critical functions */
  474.     if (pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
  475.         return(EPERM);
  476.     /* Load the current values of allocated PCI address spaces */
  477.     PCI_ADDR_SPACE_LIMITS_LOAD();
  478.     
  479.     /* Try to read the device-id/vendor-id from the config space */
  480.     cfgw = bridge->b_type0_cfg_dev[slot].l;
  481.     if (pcibr_probe_slot(bridge, cfgw, &idword)) 
  482. return(ENODEV);
  483.     slotp = &pcibr_soft->bs_slot[slot];
  484.     slotp->slot_status |= SLOT_POWER_UP;
  485.     vendor = 0xFFFF & idword;
  486.     /* If the vendor id is not valid then the slot is not populated
  487.      * and we are done.
  488.      */
  489.     if (vendor == 0xFFFF) 
  490. return(ENODEV);
  491.     
  492.     device = 0xFFFF & (idword >> 16);
  493.     htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
  494.     nfunc = 1;
  495.     rfunc = PCIIO_FUNC_NONE;
  496.     pfail = 0;
  497.     /* NOTE: if a card claims to be multifunction
  498.      * but only responds to config space 0, treat
  499.      * it as a unifunction card.
  500.      */
  501.     if (htype & 0x80) { /* MULTIFUNCTION */
  502. for (func = 1; func < 8; ++func) {
  503.     cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
  504.     if (pcibr_probe_slot(bridge, cfgw, &idwords[func])) {
  505. pfail |= 1 << func;
  506. continue;
  507.     }
  508.     vendor = 0xFFFF & idwords[func];
  509.     if (vendor == 0xFFFF) {
  510. pfail |= 1 << func;
  511. continue;
  512.     }
  513.     nfunc = func + 1;
  514.     rfunc = 0;
  515. }
  516. cfgw = bridge->b_type0_cfg_dev[slot].l;
  517.     }
  518.     NEWA(pcibr_infoh, nfunc);
  519.     
  520.     pcibr_soft->bs_slot[slot].bss_ninfo = nfunc;
  521.     pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
  522.     for (func = 0; func < nfunc; ++func) {
  523. unsigned                cmd_reg;
  524. if (func) {
  525.     if (pfail & (1 << func))
  526. continue;
  527.     
  528.     idword = idwords[func];
  529.     cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
  530.     
  531.     device = 0xFFFF & (idword >> 16);
  532.     htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
  533.     rfunc = func;
  534. }
  535. htype &= 0x7f;
  536. if (htype != 0x00) {
  537.     printk(KERN_WARNING  "%s pcibr: pci slot %d func %d has strange header type 0x%xn",
  538.     pcibr_soft->bs_name, slot, func, htype);
  539.     continue;
  540. }
  541. #if DEBUG && ATTACH_DEBUG
  542. printk(KERN_NOTICE   
  543. "%s pcibr: pci slot %d func %d: vendor 0x%x device 0x%x",
  544. pcibr_soft->bs_name, slot, func, vendor, device);
  545. #endif
  546. pcibr_info = pcibr_device_info_new
  547.     (pcibr_soft, slot, rfunc, vendor, device);
  548. conn_vhdl = pciio_device_info_register(pcibr_vhdl, &pcibr_info->f_c);
  549. if (func == 0)
  550.     slotp->slot_conn = conn_vhdl;
  551. #ifdef SN1_LITTLE_ENDIAN
  552. cmd_reg = cfgw[(PCI_CFG_COMMAND ^ 4) / 4];
  553. #else
  554. cmd_reg = cfgw[PCI_CFG_COMMAND / 4];
  555. #endif
  556. wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
  557. for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win) {
  558.     iopaddr_t               base, mask, code;
  559.     size_t                  size;
  560.     /*
  561.      * GET THE BASE & SIZE OF THIS WINDOW:
  562.      *
  563.      * The low two or four bits of the BASE register
  564.      * determines which address space we are in; the
  565.      * rest is a base address. BASE registers
  566.      * determine windows that are power-of-two sized
  567.      * and naturally aligned, so we can get the size
  568.      * of a window by writing all-ones to the
  569.      * register, reading it back, and seeing which
  570.      * bits are used for decode; the least
  571.      * significant nonzero bit is also the size of
  572.      * the window.
  573.      *
  574.      * WARNING: someone may already have allocated
  575.      * some PCI space to this window, and in fact
  576.      * PIO may be in process at this very moment
  577.      * from another processor (or even from this
  578.      * one, if we get interrupted)! So, if the BASE
  579.      * already has a nonzero address, be generous
  580.      * and use the LSBit of that address as the
  581.      * size; this could overstate the window size.
  582.      * Usually, when one card is set up, all are set
  583.      * up; so, since we don't bitch about
  584.      * overlapping windows, we are ok.
  585.      *
  586.      * UNFORTUNATELY, some cards do not clear their
  587.      * BASE registers on reset. I have two heuristics
  588.      * that can detect such cards: first, if the
  589.      * decode enable is turned off for the space
  590.      * that the window uses, we can disregard the
  591.      * initial value. second, if the address is
  592.      * outside the range that we use, we can disregard
  593.      * it as well.
  594.      *
  595.      * This is looking very PCI generic. Except for
  596.      * knowing how many slots and where their config
  597.      * spaces are, this window loop and the next one
  598.      * could probably be shared with other PCI host
  599.      * adapters. It would be interesting to see if
  600.      * this could be pushed up into pciio, when we
  601.      * start supporting more PCI providers.
  602.      */
  603. #ifdef SN1_LITTLE_ENDIAN
  604.     base = wptr[((win*4)^4)/4];
  605. #else
  606.     base = wptr[win];
  607. #endif
  608.     if (base & PCI_BA_IO_SPACE) {
  609. /* BASE is in I/O space. */
  610. space = PCIIO_SPACE_IO;
  611. mask = -4;
  612. code = base & 3;
  613. base = base & mask;
  614. if (base == 0) {
  615.     ; /* not assigned */
  616. } else if (!(cmd_reg & PCI_CMD_IO_SPACE)) {
  617.     base = 0; /* decode not enabled */
  618. }
  619.     } else {
  620. /* BASE is in MEM space. */
  621. space = PCIIO_SPACE_MEM;
  622. mask = -16;
  623. code = base & PCI_BA_MEM_LOCATION; /* extract BAR type */
  624. base = base & mask;
  625. if (base == 0) {
  626.     ; /* not assigned */
  627. } else if (!(cmd_reg & PCI_CMD_MEM_SPACE)) {
  628.     base = 0; /* decode not enabled */
  629. } else if (base & 0xC0000000) {
  630.     base = 0; /* outside permissable range */
  631. } else if ((code == PCI_BA_MEM_64BIT) &&
  632. #ifdef SN1_LITTLE_ENDIAN
  633.    (wptr[(((win + 1)*4)^4)/4] != 0)) {
  634. #else 
  635.    (wptr[win + 1] != 0)) {
  636. #endif /* LITTLE_ENDIAN */
  637.     base = 0; /* outside permissable range */
  638. }
  639.     }
  640.     if (base != 0) { /* estimate size */
  641. size = base & -base;
  642.     } else { /* calculate size */
  643. #ifdef SN1_LITTLE_ENDIAN
  644. wptr[((win*4)^4)/4] = ~0; /* turn on all bits */
  645. size = wptr[((win*4)^4)/4]; /* get stored bits */
  646. #else 
  647. wptr[win] = ~0; /* turn on all bits */
  648. size = wptr[win]; /* get stored bits */
  649. #endif /* LITTLE_ENDIAN */
  650. size &= mask; /* keep addr */
  651. size &= -size; /* keep lsbit */
  652. if (size == 0)
  653.     continue;
  654.     }
  655.     pcibr_info->f_window[win].w_space = space;
  656.     pcibr_info->f_window[win].w_base = base;
  657.     pcibr_info->f_window[win].w_size = size;
  658.     /*
  659.      * If this window already has PCI space
  660.      * allocated for it, "subtract" that space from
  661.      * our running freeblocks. Don't worry about
  662.      * overlaps in existing allocated windows; we
  663.      * may be overstating their sizes anyway.
  664.      */
  665.     if (base && size) {
  666. if (space == PCIIO_SPACE_IO) {
  667.     pcibr_freeblock_sub(&pci_io_fb,
  668. &pci_io_fl,
  669. base, size);
  670. } else {
  671.     pcibr_freeblock_sub(&pci_lo_fb,
  672. &pci_lo_fl,
  673. base, size);
  674.     pcibr_freeblock_sub(&pci_hi_fb,
  675. &pci_hi_fl,
  676. base, size);
  677. }
  678.     }
  679. #if defined(IOC3_VENDOR_ID_NUM) && defined(IOC3_DEVICE_ID_NUM)
  680.     /*
  681.      * IOC3 BASE_ADDR* BUG WORKAROUND
  682.      *
  683.      
  684.      * If we write to BASE1 on the IOC3, the
  685.      * data in BASE0 is replaced. The
  686.      * original workaround was to remember
  687.      * the value of BASE0 and restore it
  688.      * when we ran off the end of the BASE
  689.      * registers; however, a later
  690.      * workaround was added (I think it was
  691.      * rev 1.44) to avoid setting up
  692.      * anything but BASE0, with the comment
  693.      * that writing all ones to BASE1 set
  694.      * the enable-parity-error test feature
  695.      * in IOC3's SCR bit 14.
  696.      *
  697.      * So, unless we defer doing any PCI
  698.      * space allocation until drivers
  699.      * attach, and set up a way for drivers
  700.      * (the IOC3 in paricular) to tell us
  701.      * generically to keep our hands off
  702.      * BASE registers, we gotta "know" about
  703.      * the IOC3 here.
  704.      *
  705.      * Too bad the PCI folks didn't reserve the
  706.      * all-zero value for 'no BASE here' (it is a
  707.      * valid code for an uninitialized BASE in
  708.      * 32-bit PCI memory space).
  709.      */
  710.     
  711.     if ((vendor == IOC3_VENDOR_ID_NUM) &&
  712. (device == IOC3_DEVICE_ID_NUM))
  713. break;
  714. #endif
  715.     if (code == PCI_BA_MEM_64BIT) {
  716. win++; /* skip upper half */
  717. #ifdef SN1_LITTLE_ENDIAN
  718. wptr[((win*4)^4)/4] = 0; /* which must be zero */
  719. #else 
  720. wptr[win] = 0; /* which must be zero */
  721. #endif /* LITTLE_ENDIAN */
  722.     }
  723. } /* next win */
  724.     } /* next func */
  725.     /* Store back the values for allocated PCI address spaces */
  726.     PCI_ADDR_SPACE_LIMITS_STORE();
  727.     return(0);
  728. }
  729. /*
  730.  * pcibr_slot_info_free
  731.  * Remove all the PCI infrastructural information associated
  732.  *  with a particular PCI device.
  733.  */
  734. int
  735. pcibr_slot_info_free(devfs_handle_t pcibr_vhdl,
  736.                      pciio_slot_t slot)
  737. {
  738.     pcibr_soft_t pcibr_soft;
  739.     pcibr_info_h pcibr_infoh;
  740.     int nfunc;
  741.     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
  742.     if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
  743. return(EINVAL);
  744.     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
  745.     pcibr_device_info_free(pcibr_vhdl, slot);
  746.     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
  747.     DELA(pcibr_infoh,nfunc);
  748.     pcibr_soft->bs_slot[slot].bss_ninfo = 0;
  749.     return(0);
  750. }
  751. int as_debug = 0;
  752. /*
  753.  * pcibr_slot_addr_space_init
  754.  * Reserve chunks of PCI address space as required by 
  755.  *  the base registers in the card.
  756.  */
  757. int
  758. pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,
  759.    pciio_slot_t slot)
  760. {
  761.     pcibr_soft_t pcibr_soft;
  762.     pcibr_info_h pcibr_infoh;
  763.     pcibr_info_t pcibr_info;
  764.     bridge_t *bridge;
  765.     iopaddr_t pci_io_fb, pci_io_fl;
  766.     iopaddr_t pci_lo_fb, pci_lo_fl;
  767.     iopaddr_t pci_hi_fb, pci_hi_fl;
  768.     size_t              align;
  769.     iopaddr_t           mask;
  770.     int      nbars;
  771.     int         nfunc;
  772.     int func;
  773.     int win;
  774.     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
  775.     if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
  776. return(EINVAL);
  777.     bridge = pcibr_soft->bs_base;
  778.     /* Get the current values for the allocated PCI address spaces */
  779.     PCI_ADDR_SPACE_LIMITS_LOAD();
  780.     if (as_debug)
  781. #ifdef LATER
  782.     PCI_ADDR_SPACE_LIMITS_PRINT();
  783. #endif
  784.     /* allocate address space,
  785.      * for windows that have not been
  786.      * previously assigned.
  787.      */
  788.     if (pcibr_soft->bs_slot[slot].has_host) {
  789. return(0);
  790.     }
  791.     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
  792.     if (nfunc < 1)
  793. return(EINVAL);
  794.     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
  795.     if (!pcibr_infoh)
  796. return(EINVAL);
  797.     /*
  798.      * Try to make the DevIO windows not
  799.      * overlap by pushing the "io" and "hi"
  800.      * allocation areas up to the next one
  801.      * or two megabyte bound. This also
  802.      * keeps them from being zero.
  803.      *
  804.      * DO NOT do this with "pci_lo" since
  805.      * the entire "lo" area is only a
  806.      * megabyte, total ...
  807.      */
  808.     align = (slot < 2) ? 0x200000 : 0x100000;
  809.     mask = -align;
  810.     pci_io_fb = (pci_io_fb + align - 1) & mask;
  811.     pci_hi_fb = (pci_hi_fb + align - 1) & mask;
  812.     for (func = 0; func < nfunc; ++func) {
  813. cfg_p                   cfgw;
  814. cfg_p                   wptr;
  815. pciio_space_t           space;
  816. iopaddr_t               base;
  817. size_t                  size;
  818. cfg_p                   pci_cfg_cmd_reg_p;
  819. unsigned                pci_cfg_cmd_reg;
  820. unsigned                pci_cfg_cmd_reg_add = 0;
  821. pcibr_info = pcibr_infoh[func];
  822. if (!pcibr_info)
  823.     continue;
  824. if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
  825.     continue;
  826. cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
  827. wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
  828. nbars = PCI_CFG_BASE_ADDRS;
  829. for (win = 0; win < nbars; ++win) {
  830.     space = pcibr_info->f_window[win].w_space;
  831.     base = pcibr_info->f_window[win].w_base;
  832.     size = pcibr_info->f_window[win].w_size;
  833.     
  834.     if (size < 1)
  835. continue;
  836.     if (base >= size) {
  837. #if DEBUG && PCI_DEBUG
  838. printk("pcibr: slot %d func %d window %d is in %d[0x%x..0x%x], alloc by promn",
  839. slot, func, win, space, base, base + size - 1);
  840. #endif
  841. continue; /* already allocated */
  842.     }
  843.     align = size; /* ie. 0x00001000 */
  844.     if (align < _PAGESZ)
  845. align = _PAGESZ; /* ie. 0x00004000 */
  846.     mask = -align; /* ie. 0xFFFFC000 */
  847.     switch (space) {
  848.     case PCIIO_SPACE_IO:
  849. base = (pci_io_fb + align - 1) & mask;
  850. if ((base + size) > pci_io_fl) {
  851.     base = 0;
  852.     break;
  853. }
  854. pci_io_fb = base + size;
  855. break;
  856.     case PCIIO_SPACE_MEM:
  857. #ifdef SN1_LITTLE_ENDIAN
  858. if ((wptr[((win*4)^4)/4] & PCI_BA_MEM_LOCATION) ==
  859. #else
  860. if ((wptr[win] & PCI_BA_MEM_LOCATION) ==
  861. #endif  /* LITTLE_ENDIAN */
  862.     PCI_BA_MEM_1MEG) {
  863.     /* allocate from 20-bit PCI space */
  864.     base = (pci_lo_fb + align - 1) & mask;
  865.     if ((base + size) > pci_lo_fl) {
  866. base = 0;
  867. break;
  868.     }
  869.     pci_lo_fb = base + size;
  870. } else {
  871.     /* allocate from 32-bit or 64-bit PCI space */
  872.     base = (pci_hi_fb + align - 1) & mask;
  873.     if ((base + size) > pci_hi_fl) {
  874. base = 0;
  875. break;
  876.     }
  877.     pci_hi_fb = base + size;
  878. }
  879. break;
  880.     default:
  881. base = 0;
  882. #if DEBUG && PCI_DEBUG
  883. printk("pcibr: slot %d window %d had bad space code %dn",
  884. slot, win, space);
  885. #endif
  886.     }
  887.     pcibr_info->f_window[win].w_base = base;
  888. #ifdef SN1_LITTLE_ENDIAN
  889.     wptr[((win*4)^4)/4] = base;
  890. #if DEBUG && PCI_DEBUG
  891. printk("Setting base address 0x%p base 0x%xn", &(wptr[((win*4)^4)/4]), base);
  892. #endif
  893. #else
  894.     wptr[win] = base;
  895. #endif  /* LITTLE_ENDIAN */
  896. #if DEBUG && PCI_DEBUG
  897.     if (base >= size)
  898. printk("pcibr: slot %d func %d window %d is in %d [0x%x..0x%x], alloc by pcibrn",
  899. slot, func, win, space, base, base + size - 1);
  900.     else
  901. printk("pcibr: slot %d func %d window %d, unable to alloc 0x%x in 0x%pn",
  902. slot, func, win, size, space);
  903. #endif
  904. } /* next base */
  905. /*
  906.  * Allocate space for the EXPANSION ROM
  907.  * NOTE: DO NOT DO THIS ON AN IOC3,
  908.  * as it blows the system away.
  909.  */
  910. base = size = 0;
  911. if ((pcibr_soft->bs_slot[slot].bss_vendor_id != IOC3_VENDOR_ID_NUM) ||
  912.     (pcibr_soft->bs_slot[slot].bss_device_id != IOC3_DEVICE_ID_NUM)) {
  913.     wptr = cfgw + PCI_EXPANSION_ROM / 4;
  914. #ifdef SN1_LITTLE_ENDIAN
  915.     wptr[1] = 0xFFFFF000;
  916.     mask = wptr[1];
  917. #else
  918.     *wptr = 0xFFFFF000;
  919.     mask = *wptr;
  920. #endif  /* LITTLE_ENDIAN */
  921.     if (mask & 0xFFFFF000) {
  922. size = mask & -mask;
  923. align = size;
  924. if (align < _PAGESZ)
  925.     align = _PAGESZ;
  926. mask = -align;
  927. base = (pci_hi_fb + align - 1) & mask;
  928. if ((base + size) > pci_hi_fl)
  929.     base = size = 0;
  930. else {
  931.     pci_hi_fb = base + size;
  932. #ifdef SN1_LITTLE_ENDIAN
  933.     wptr[1] = base;
  934. #else
  935.     *wptr = base;
  936. #endif  /* LITTLE_ENDIAN */
  937. #if DEBUG && PCI_DEBUG
  938.     printk("%s/%d ROM in 0x%lx..0x%lx (alloc by pcibr)n",
  939.     pcibr_soft->bs_name, slot,
  940.     base, base + size - 1);
  941. #endif
  942. }
  943.     }
  944. }
  945. pcibr_info->f_rbase = base;
  946. pcibr_info->f_rsize = size;
  947. /*
  948.  * if necessary, update the board's
  949.  * command register to enable decoding
  950.  * in the windows we added.
  951.  *
  952.  * There are some bits we always want to
  953.  * be sure are set.
  954.  */
  955. pci_cfg_cmd_reg_add |= PCI_CMD_IO_SPACE;
  956. /*
  957.  * The Adaptec 1160 FC Controller WAR #767995:
  958.  * The part incorrectly ignores the upper 32 bits of a 64 bit
  959.  * address when decoding references to it's registers so to
  960.  * keep it from responding to a bus cycle that it shouldn't
  961.  * we only use I/O space to get at it's registers.  Don't
  962.  * enable memory space accesses on that PCI device.
  963.  */
  964. #define FCADP_VENDID 0x9004 /* Adaptec Vendor ID from fcadp.h */
  965. #define FCADP_DEVID 0x1160  /* Adaptec 1160 Device ID from fcadp.h */
  966. if ((pcibr_info->f_vendor != FCADP_VENDID) ||
  967.     (pcibr_info->f_device != FCADP_DEVID))
  968.     pci_cfg_cmd_reg_add |= PCI_CMD_MEM_SPACE;
  969. pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER;
  970. pci_cfg_cmd_reg_p = cfgw + PCI_CFG_COMMAND / 4;
  971. pci_cfg_cmd_reg = *pci_cfg_cmd_reg_p;
  972. #if PCI_FBBE /* XXX- check here to see if dev can do fast-back-to-back */
  973. if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP))
  974.     fast_back_to_back_enable = 0;
  975. #endif
  976. pci_cfg_cmd_reg &= 0xFFFF;
  977. if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg)
  978.     *pci_cfg_cmd_reg_p = pci_cfg_cmd_reg | pci_cfg_cmd_reg_add;
  979.     } /* next func */
  980.     /* Now that we have allocated new chunks of PCI address spaces to this
  981.      * card we need to update the bookkeeping values which indicate
  982.      * the current PCI address space allocations.
  983.      */
  984.     PCI_ADDR_SPACE_LIMITS_STORE();
  985.     return(0);
  986. }
  987. /*
  988.  * pcibr_slot_device_init
  989.  *  Setup the device register in the bridge for this PCI slot.
  990.  */
  991. int
  992. pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,
  993.        pciio_slot_t slot)
  994. {
  995.     pcibr_soft_t  pcibr_soft;
  996.     bridge_t *bridge;
  997.     bridgereg_t  devreg;
  998.     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
  999.     if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
  1000. return(EINVAL);
  1001.     bridge = pcibr_soft->bs_base;
  1002.     /*
  1003.      * Adjustments to Device(x)
  1004.      * and init of bss_device shadow
  1005.      */
  1006.     devreg = bridge->b_device[slot].reg;
  1007.     devreg &= ~BRIDGE_DEV_PAGE_CHK_DIS;
  1008.     devreg |= BRIDGE_DEV_COH | BRIDGE_DEV_VIRTUAL_EN;
  1009. #ifdef LITTLE_ENDIAN
  1010.     devreg |= BRIDGE_DEV_DEV_SWAP;
  1011. #endif
  1012.     pcibr_soft->bs_slot[slot].bss_device = devreg;
  1013.     bridge->b_device[slot].reg = devreg;
  1014. #if DEBUG && PCI_DEBUG
  1015. printk("pcibr Device(%d): 0x%lxn", slot, bridge->b_device[slot].reg);
  1016. #endif
  1017. #if DEBUG && PCI_DEBUG
  1018.     printk("pcibr: PCI space allocation done.n");
  1019. #endif
  1020.     return(0);
  1021. }
  1022. /*
  1023.  * pcibr_slot_guest_info_init
  1024.  * Setup the host/guest relations for a PCI slot.
  1025.  */
  1026. int
  1027. pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,
  1028.    pciio_slot_t slot)
  1029. {
  1030.     pcibr_soft_t pcibr_soft;
  1031.     pcibr_info_h pcibr_infoh;
  1032.     pcibr_info_t pcibr_info;
  1033.     pcibr_soft_slot_t slotp;
  1034.     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
  1035.     if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
  1036. return(EINVAL);
  1037.     slotp = &pcibr_soft->bs_slot[slot];
  1038.     /* create info and verticies for guest slots;
  1039.      * for compatibilitiy macros, create info
  1040.      * for even unpopulated slots (but do not
  1041.      * build verticies for them).
  1042.      */
  1043.     if (pcibr_soft->bs_slot[slot].bss_ninfo < 1) {
  1044. NEWA(pcibr_infoh, 1);
  1045. pcibr_soft->bs_slot[slot].bss_ninfo = 1;
  1046. pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
  1047. pcibr_info = pcibr_device_info_new
  1048.     (pcibr_soft, slot, PCIIO_FUNC_NONE,
  1049.      PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
  1050. if (pcibr_soft->bs_slot[slot].has_host) {
  1051.     slotp->slot_conn = pciio_device_info_register
  1052. (pcibr_vhdl, &pcibr_info->f_c);
  1053. }
  1054.     }
  1055.     /* generate host/guest relations
  1056.      */
  1057.     if (pcibr_soft->bs_slot[slot].has_host) {
  1058. int  host = pcibr_soft->bs_slot[slot].host_slot;
  1059. pcibr_soft_slot_t host_slotp = &pcibr_soft->bs_slot[host];
  1060. hwgraph_edge_add(slotp->slot_conn,
  1061.  host_slotp->slot_conn,
  1062.  EDGE_LBL_HOST);
  1063. /* XXX- only gives us one guest edge per
  1064.  * host. If/when we have a host with more than
  1065.  * one guest, we will need to figure out how
  1066.  * the host finds all its guests, and sorts
  1067.  * out which one is which.
  1068.  */
  1069. hwgraph_edge_add(host_slotp->slot_conn,
  1070.  slotp->slot_conn,
  1071.  EDGE_LBL_GUEST);
  1072.     }
  1073.     return(0);
  1074. }
  1075. /*
  1076.  * pcibr_slot_call_device_attach
  1077.  * This calls the associated driver attach routine for the PCI
  1078.  *  card in this slot.
  1079.  */
  1080. int
  1081. pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
  1082.       pciio_slot_t slot,
  1083.       int          drv_flags)
  1084. {
  1085.     pcibr_soft_t pcibr_soft;
  1086.     pcibr_info_h pcibr_infoh;
  1087.     pcibr_info_t pcibr_info;
  1088.     async_attach_t aa = NULL;
  1089.     int func;
  1090.     devfs_handle_t xconn_vhdl,conn_vhdl;
  1091.     int nfunc;
  1092.     int                 error_func;
  1093.     int                 error_slot = 0;
  1094.     int                 error = ENODEV;
  1095.     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
  1096.     if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
  1097. return(EINVAL);
  1098.     if (pcibr_soft->bs_slot[slot].has_host) {
  1099.         return(EPERM);
  1100.     }
  1101.     
  1102.     xconn_vhdl = pcibr_soft->bs_conn;
  1103.     aa = async_attach_get_info(xconn_vhdl);
  1104.     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
  1105.     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
  1106.     for (func = 0; func < nfunc; ++func) {
  1107. pcibr_info = pcibr_infoh[func];
  1108. if (!pcibr_info)
  1109.     continue;
  1110. if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
  1111.     continue;
  1112. conn_vhdl = pcibr_info->f_vertex;
  1113. #ifdef LATER
  1114. /*
  1115.  * Activate if and when we support cdl.
  1116.  */
  1117. if (aa)
  1118.     async_attach_add_info(conn_vhdl, aa);
  1119. #endif /* LATER */
  1120. error_func = pciio_device_attach(conn_vhdl, drv_flags);
  1121.         pcibr_info->f_att_det_error = error_func;
  1122. if (error_func)
  1123.     error_slot = error_func;
  1124.         error = error_slot;
  1125.     } /* next func */
  1126.     if (error) {
  1127. if ((error != ENODEV) && (error != EUNATCH))
  1128.     pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_INCMPLT;
  1129.     } else {
  1130.         pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_CMPLT;
  1131.     }
  1132.         
  1133.     return(error);
  1134. }
  1135. /*
  1136.  * pcibr_slot_call_device_detach
  1137.  * This calls the associated driver detach routine for the PCI
  1138.  *  card in this slot.
  1139.  */
  1140. int
  1141. pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
  1142.       pciio_slot_t slot,
  1143.       int          drv_flags)
  1144. {
  1145.     pcibr_soft_t pcibr_soft;
  1146.     pcibr_info_h pcibr_infoh;
  1147.     pcibr_info_t pcibr_info;
  1148.     int func;
  1149.     devfs_handle_t conn_vhdl = GRAPH_VERTEX_NONE;
  1150.     int nfunc;
  1151.     int                 error_func;
  1152.     int                 error_slot = 0;
  1153.     int                 error = ENODEV;
  1154.     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
  1155.     if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
  1156. return(EINVAL);
  1157.     if (pcibr_soft->bs_slot[slot].has_host)
  1158.         return(EPERM);
  1159.     /* Make sure that we do not detach a system critical function vertex */
  1160.     if(pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
  1161.         return(EPERM);
  1162.     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
  1163.     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
  1164.     for (func = 0; func < nfunc; ++func) {
  1165. pcibr_info = pcibr_infoh[func];
  1166. if (!pcibr_info)
  1167.     continue;
  1168. if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
  1169.     continue;
  1170. conn_vhdl = pcibr_info->f_vertex;
  1171. error_func = pciio_device_detach(conn_vhdl, drv_flags);
  1172.         pcibr_info->f_att_det_error = error_func;
  1173. if (error_func)
  1174.     error_slot = error_func;
  1175. error = error_slot;
  1176.     } /* next func */
  1177.     pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;
  1178.     if (error) {
  1179. if ((error != ENODEV) && (error != EUNATCH))
  1180.             pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_INCMPLT;
  1181.     } else {
  1182.         if (conn_vhdl != GRAPH_VERTEX_NONE) 
  1183.             pcibr_device_unregister(conn_vhdl);
  1184.         pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_CMPLT;
  1185.     }
  1186.         
  1187.     return(error);
  1188. }
  1189. #ifdef LATER
  1190. /*
  1191.  * pcibr_slot_attach
  1192.  * This is a place holder routine to keep track of all the
  1193.  * slot-specific initialization that needs to be done.
  1194.  * This is usually called when we want to initialize a new
  1195.  *  PCI card on the bus.
  1196.  */
  1197. int
  1198. pcibr_slot_attach(devfs_handle_t pcibr_vhdl,
  1199.   pciio_slot_t slot,
  1200.   int          drv_flags,
  1201.   char        *l1_msg,
  1202.                   int         *sub_errorp)
  1203. {
  1204.     pcibr_soft_t  pcibr_soft = pcibr_soft_get(pcibr_vhdl);
  1205.     timespec_t    ts;
  1206.     int   error;
  1207.     if (!(pcibr_soft->bs_slot[slot].slot_status & SLOT_POWER_UP)) { 
  1208.         /* Power-up the slot */
  1209.         error = pcibr_slot_pwr(pcibr_vhdl, slot, L1_REQ_PCI_UP, l1_msg);
  1210.         if (error) {
  1211.             if (sub_errorp)
  1212.                 *sub_errorp = error;
  1213.             return(PCI_L1_ERR);
  1214.         } else {
  1215.             pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_POWER_MASK;
  1216.             pcibr_soft->bs_slot[slot].slot_status |= SLOT_POWER_UP;
  1217.         }
  1218. #ifdef LATER
  1219.         /*
  1220.          * Allow cards like the Alteon Gigabit Ethernet Adapter to complete
  1221.          * on-card initialization following the slot reset
  1222.          */
  1223.          ts.tv_sec = 0;                      /* 0 secs */
  1224.          ts.tv_nsec = 500 * (1000 * 1000);   /* 500 msecs */
  1225.          nano_delay(&ts);
  1226. #else
  1227. #endif
  1228. #if 0
  1229.         /* Reset the slot */
  1230.         error = pcibr_slot_reset(pcibr_vhdl, slot)
  1231.         if (error) {
  1232.             if (sub_errorp)
  1233.                 *sub_errorp = error;
  1234.             return(PCI_SLOT_RESET_ERR);
  1235.         }
  1236. #endif
  1237.         /* Find out what is out there */
  1238.         error = pcibr_slot_info_init(pcibr_vhdl, slot);
  1239.         if (error) {
  1240.             if (sub_errorp)
  1241.                 *sub_errorp = error;
  1242.             return(PCI_SLOT_INFO_INIT_ERR);
  1243.         }
  1244.         /* Set up the address space for this slot in the PCI land */
  1245.         error = pcibr_slot_addr_space_init(pcibr_vhdl, slot);
  1246.         if (error) {
  1247.             if (sub_errorp)
  1248.                 *sub_errorp = error;
  1249.             return(PCI_SLOT_ADDR_INIT_ERR);
  1250.         }
  1251.         /* Setup the device register */
  1252.         error = pcibr_slot_device_init(pcibr_vhdl, slot);
  1253.         if (error) {
  1254.             if (sub_errorp)
  1255.                 *sub_errorp = error;
  1256.             return(PCI_SLOT_DEV_INIT_ERR);
  1257.         }
  1258.         /* Setup host/guest relations */
  1259.         error = pcibr_slot_guest_info_init(pcibr_vhdl, slot);
  1260.         if (error) {
  1261.             if (sub_errorp)
  1262.                 *sub_errorp = error;
  1263.             return(PCI_SLOT_GUEST_INIT_ERR);
  1264.         }
  1265.         /* Initial RRB management */
  1266.         error = pcibr_slot_initial_rrb_alloc(pcibr_vhdl, slot);
  1267.         if (error) {
  1268.             if (sub_errorp)
  1269.                 *sub_errorp = error;
  1270.             return(PCI_SLOT_RRB_ALLOC_ERR);
  1271.         }
  1272.     }
  1273.     /* Call the device attach */
  1274.     error = pcibr_slot_call_device_attach(pcibr_vhdl, slot, drv_flags);
  1275.     if (error) {
  1276.         if (sub_errorp)
  1277.             *sub_errorp = error;
  1278.         if (error == EUNATCH)
  1279.             return(PCI_NO_DRIVER);
  1280.         else
  1281.             return(PCI_SLOT_DRV_ATTACH_ERR);
  1282.     }
  1283.     return(0);
  1284. }
  1285. #endif /* LATER */
  1286. /*
  1287.  * pcibr_slot_detach
  1288.  * This is a place holder routine to keep track of all the
  1289.  * slot-specific freeing that needs to be done.
  1290.  */
  1291. int
  1292. pcibr_slot_detach(devfs_handle_t pcibr_vhdl,
  1293.   pciio_slot_t slot,
  1294.   int          drv_flags)
  1295. {
  1296.     int   error;
  1297.     
  1298.     /* Call the device detach function */
  1299.     error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags));
  1300.     return (error);
  1301. }
  1302. /*
  1303.  * pcibr_is_slot_sys_critical
  1304.  *      Check slot for any functions that are system critical.
  1305.  *      Return 1 if any are system critical or 0 otherwise.
  1306.  *
  1307.  *      This function will always return 0 when called by 
  1308.  *      pcibr_attach() because the system critical vertices 
  1309.  *      have not yet been set in the hwgraph.
  1310.  */
  1311. int
  1312. pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl,
  1313.                       pciio_slot_t slot)
  1314. {
  1315.     pcibr_soft_t        pcibr_soft;
  1316.     pcibr_info_h        pcibr_infoh;
  1317.     pcibr_info_t        pcibr_info;
  1318.     devfs_handle_t        conn_vhdl = GRAPH_VERTEX_NONE;
  1319.     int                 nfunc;
  1320.     int                 func;
  1321.     boolean_t is_sys_critical_vertex(devfs_handle_t);
  1322.     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
  1323.     if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
  1324.         return(0);
  1325.     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
  1326.     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
  1327.     for (func = 0; func < nfunc; ++func) {
  1328.         pcibr_info = pcibr_infoh[func];
  1329.         if (!pcibr_info)
  1330.             continue;
  1331.         if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
  1332.             continue;
  1333.         conn_vhdl = pcibr_info->f_vertex;
  1334.         if (is_sys_critical_vertex(conn_vhdl)) { 
  1335. #if defined(SUPPORT_PRINTING_V_FORMAT)
  1336.             printk(KERN_WARNING  "%v is a system critical device vertexn", conn_vhdl);
  1337. #else
  1338.             printk(KERN_WARNING  "%p is a system critical device vertexn", (void *)conn_vhdl);
  1339. #endif
  1340.             return(1); 
  1341.         }
  1342.     }
  1343.     return(0);
  1344. }
  1345. /*
  1346.  * pcibr_probe_slot: read a config space word
  1347.  * while trapping any errors; reutrn zero if
  1348.  * all went OK, or nonzero if there was an error.
  1349.  * The value read, if any, is passed back
  1350.  * through the valp parameter.
  1351.  */
  1352. int
  1353. pcibr_probe_slot(bridge_t *bridge,
  1354.  cfg_p cfg,
  1355.  unsigned *valp)
  1356. {
  1357.     int                     rv;
  1358.     bridgereg_t             old_enable, new_enable;
  1359.     int badaddr_val(volatile void *, int, volatile void *);
  1360.     old_enable = bridge->b_int_enable;
  1361.     new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
  1362.     bridge->b_int_enable = new_enable;
  1363. /*
  1364.  * The xbridge doesn't clear b_err_int_view unless
  1365.  * multi-err is cleared...
  1366.  */
  1367. if (is_xbridge(bridge))
  1368.     if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
  1369. bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
  1370.     }
  1371.     if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) {
  1372. bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR;
  1373. (void) bridge->b_wid_tflush; /* flushbus */
  1374.     }
  1375.     rv = badaddr_val((void *) cfg, 4, valp);
  1376. /*
  1377.  * The xbridge doesn't set master timeout in b_int_status
  1378.  * here.  Fortunately it's in error_interrupt_view.
  1379.  */
  1380. if (is_xbridge(bridge))
  1381.     if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
  1382. bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
  1383. rv = 1; /* unoccupied slot */
  1384.     }
  1385.     bridge->b_int_enable = old_enable;
  1386.     bridge->b_wid_tflush; /* wait until Bridge PIO complete */
  1387.     return rv;
  1388. }
  1389. void
  1390. pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot)
  1391. {
  1392.     pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl);
  1393.     pcibr_info_t pcibr_info;
  1394.     pciio_function_t func;
  1395.     pcibr_soft_slot_t slotp = &pcibr_soft->bs_slot[slot];
  1396.     int nfunc = slotp->bss_ninfo;
  1397.     int                 bar;
  1398.     int                 devio_index;
  1399.     int                 s;
  1400.     for (func = 0; func < nfunc; func++) {
  1401. pcibr_info = slotp->bss_infos[func];
  1402. if (!pcibr_info) 
  1403.     continue;
  1404.         s = pcibr_lock(pcibr_soft);
  1405.         for (bar = 0; bar < PCI_CFG_BASE_ADDRS; bar++) {
  1406.             if (pcibr_info->f_window[bar].w_space == PCIIO_SPACE_NONE)
  1407.                 continue;
  1408.             /* Get index of the DevIO(x) register used to access this BAR */
  1409.             devio_index = pcibr_info->f_window[bar].w_devio_index;
  1410.  
  1411.             /* On last use, clear the DevIO(x) used to access this BAR */
  1412.             if (! --pcibr_soft->bs_slot[devio_index].bss_devio.bssd_ref_cnt) {
  1413.                pcibr_soft->bs_slot[devio_index].bss_devio.bssd_space =
  1414.                                                        PCIIO_SPACE_NONE; 
  1415.                pcibr_soft->bs_slot[devio_index].bss_devio.bssd_base =
  1416.                                                        PCIBR_D32_BASE_UNSET;
  1417.                pcibr_soft->bs_slot[devio_index].bss_device = 0;
  1418.             }
  1419.         }
  1420.         pcibr_unlock(pcibr_soft, s);
  1421. slotp->bss_infos[func] = 0;
  1422. pciio_device_info_unregister(pcibr_vhdl, &pcibr_info->f_c);
  1423. pciio_device_info_free(&pcibr_info->f_c);
  1424. DEL(pcibr_info);
  1425.     }
  1426.     /* Reset the mapping usage counters */
  1427.     slotp->bss_pmu_uctr = 0;
  1428.     slotp->bss_d32_uctr = 0;
  1429.     slotp->bss_d64_uctr = 0;
  1430.     /* Clear the Direct translation info */
  1431.     slotp->bss_d64_base = PCIBR_D64_BASE_UNSET;
  1432.     slotp->bss_d64_flags = 0;
  1433.     slotp->bss_d32_base = PCIBR_D32_BASE_UNSET;
  1434.     slotp->bss_d32_flags = 0;
  1435.     /* Clear out shadow info necessary for the external SSRAM workaround */
  1436.     slotp->bss_ext_ates_active = ATOMIC_INIT(0);
  1437.     slotp->bss_cmd_pointer = 0;
  1438.     slotp->bss_cmd_shadow = 0;
  1439. }