static pciio_provider_t * pciio_to_provider_fns(devfs_handle_t dev) { pciio_info_t card_info; pciio_provider_t *provider_fns; /* * We're called with two types of vertices, one is * the bridge vertex (ends with "pci") and the other is the * pci slot vertex (ends with "pci/[0-8]"). For the first type * we need to get the provider from the PFUNCS label. For * the second we get it from fastinfo/c_pops. */ provider_fns = pciio_provider_fns_get(dev); if (provider_fns == NULL) { card_info = pciio_info_get(dev); if (card_info != NULL) { provider_fns = pciio_info_pops_get(card_info); } } if (provider_fns == NULL) #if defined(SUPPORT_PRINTING_V_FORMAT) PRINT_PANIC("%v: provider_fns == NULL", dev); #else PRINT_PANIC("0x%x: provider_fns == NULL", dev); #endif return provider_fns; }
int pciio_device_detach(devfs_handle_t pconn, int drv_flags) { pciio_info_t pciio_info; pciio_vendor_id_t vendor_id; pciio_device_id_t device_id; pciio_device_inventory_remove(pconn); pciio_info = pciio_info_get(pconn); vendor_id = pciio_info->c_vendor; device_id = pciio_info->c_device; /* we don't start attaching things until * all the driver init routines (including * pciio_init) have been called; so we * can assume here that we have a registry. */ ASSERT(pciio_registry != NULL); return(cdl_del_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags)); }
pciio_provider_t * pciio_to_provider_fns(vertex_hdl_t dev) { pciio_info_t card_info; pciio_provider_t *provider_fns; /* * We're called with two types of vertices, one is * the bridge vertex (ends with "pci") and the other is the * pci slot vertex (ends with "pci/[0-8]"). For the first type * we need to get the provider from the PFUNCS label. For * the second we get it from fastinfo/c_pops. */ provider_fns = pciio_provider_fns_get(dev); if (provider_fns == NULL) { card_info = pciio_info_get(dev); if (card_info != NULL) { provider_fns = pciio_info_pops_get(card_info); } } if (provider_fns == NULL) { char devname[MAXDEVNAME]; panic("%s: provider_fns == NULL", vertex_to_name(dev, devname, MAXDEVNAME)); } return provider_fns; }
/* * pciio_error_register: * arrange for a function to be called with * a specified first parameter plus other * information when an error is encountered * and traced to the pci slot corresponding * to the connection point pconn. * * may also be called with a null function * pointer to "unregister" the error handler. * * NOTE: subsequent calls silently overwrite * previous data for this vertex. We assume that * cooperating drivers, well, cooperate ... */ void pciio_error_register(devfs_handle_t pconn, error_handler_f *efunc, error_handler_arg_t einfo) { pciio_info_t pciio_info; pciio_info = pciio_info_get(pconn); ASSERT(pciio_info != NULL); pciio_info->c_efunc = efunc; pciio_info->c_einfo = einfo; }
/* * Check if any device has been found in this slot, and return * true or false * vhdl is the vertex for the slot */ int pciio_slot_inuse(devfs_handle_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); ASSERT(pciio_info); ASSERT(pciio_info->c_vertex == pconn_vhdl); if (pciio_info->c_vendor) { /* * Non-zero value for vendor indicate * a board being found in this slot. */ return 1; } return 0; }
/* Add the pci card inventory information to the hwgraph */ static void pciio_device_inventory_add(devfs_handle_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); ASSERT(pciio_info); ASSERT(pciio_info->c_vertex == pconn_vhdl); /* Donot add inventory for non-existent devices */ if ((pciio_info->c_vendor == PCIIO_VENDOR_ID_NONE) || (pciio_info->c_device == PCIIO_DEVICE_ID_NONE)) return; device_inventory_add(pconn_vhdl,INV_IOBD,INV_PCIADAP, pciio_info->c_vendor,pciio_info->c_device, pciio_info->c_slot); }
/*ARGSUSED */ int pciio_device_attach(vertex_hdl_t pconn, int drv_flags) { pciio_info_t pciio_info; pciio_vendor_id_t vendor_id; pciio_device_id_t device_id; pciio_device_inventory_add(pconn); pciio_info = pciio_info_get(pconn); vendor_id = pciio_info->c_vendor; device_id = pciio_info->c_device; /* we don't start attaching things until * all the driver init routines (including * pciio_init) have been called; so we * can assume here that we have a registry. */ return(cdl_add_connpt(vendor_id, device_id, pconn, drv_flags)); }
/* * For the given device, initialize the addresses for both the Device(x) Flush * Write Buffer register and the Xbow Flush Register for the port the PCI bus * is connected. */ static void set_flush_addresses(struct pci_dev *device_dev, struct sn_device_sysdata *device_sysdata) { pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl); pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); bridge_t *bridge = pcibr_soft->bs_base; device_sysdata->dma_buf_sync = (volatile unsigned int *) &(bridge->b_wr_req_buf[pciio_slot].reg); device_sysdata->xbow_buf_sync = (volatile unsigned int *) XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(get_nasid(), 0), pcibr_soft->bs_xid); #ifdef DEBUG printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync); while((volatile unsigned int )*device_sysdata->dma_buf_sync); while((volatile unsigned int )*device_sysdata->xbow_buf_sync); #endif }