📄 pciio.c
字号:
devfs_handle_tpciio_info_dev_get(pciio_info_t pciio_info){ return (pciio_info->c_vertex);}/*ARGSUSED*/pciio_bus_tpciio_info_bus_get(pciio_info_t pciio_info){ /* XXX for now O2 always gets back bus 0 */ return (pciio_bus_t)0;}pciio_slot_tpciio_info_slot_get(pciio_info_t pciio_info){ return (pciio_info->c_slot);}pciio_function_tpciio_info_function_get(pciio_info_t pciio_info){ return (pciio_info->c_func);}pciio_vendor_id_tpciio_info_vendor_id_get(pciio_info_t pciio_info){ return (pciio_info->c_vendor);}pciio_device_id_tpciio_info_device_id_get(pciio_info_t pciio_info){ return (pciio_info->c_device);}devfs_handle_tpciio_info_master_get(pciio_info_t pciio_info){ return (pciio_info->c_master);}arbitrary_info_tpciio_info_mfast_get(pciio_info_t pciio_info){ return (pciio_info->c_mfast);}pciio_provider_t *pciio_info_pops_get(pciio_info_t pciio_info){ return (pciio_info->c_pops);}error_handler_f *pciio_info_efunc_get(pciio_info_t pciio_info){ return (pciio_info->c_efunc);}error_handler_arg_t *pciio_info_einfo_get(pciio_info_t pciio_info){ return (pciio_info->c_einfo);}pciio_space_tpciio_info_bar_space_get(pciio_info_t info, int win){ return info->c_window[win].w_space;}iopaddr_tpciio_info_bar_base_get(pciio_info_t info, int win){ return info->c_window[win].w_base;}size_tpciio_info_bar_size_get(pciio_info_t info, int win){ return info->c_window[win].w_size;}iopaddr_tpciio_info_rom_base_get(pciio_info_t info){ return info->c_rbase;}size_tpciio_info_rom_size_get(pciio_info_t info){ return info->c_rsize;}/* ===================================================================== * GENERIC PCI INITIALIZATION FUNCTIONS *//* * pciioinit: called once during device driver * initializtion if this driver is configured into * the system. */voidpciio_init(void){ cdl_p cp;#if DEBUG && ATTACH_DEBUG printf("pciio_init\n");#endif /* Allocate the registry. * We might already have one. * If we don't, go get one. * MPness: someone might have * set one up for us while we * were not looking; use an atomic * compare-and-swap to commit to * using the new registry if and * only if nobody else did first. * If someone did get there first, * toss the one we allocated back * into the pool. */ if (pciio_registry == NULL) { cp = cdl_new(EDGE_LBL_PCI, "vendor", "device"); if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) { cdl_del(cp); } } ASSERT(pciio_registry != NULL);}/* * pciioattach: called for each vertex in the graph * that is a PCI provider. *//*ARGSUSED */intpciio_attach(devfs_handle_t pciio){#if DEBUG && ATTACH_DEBUG#if defined(SUPPORT_PRINTING_V_FORMAT) printk("%v: pciio_attach\n", pciio);#else printk("0x%x: pciio_attach\n", pciio);#endif#endif return 0;}/* * Associate a set of pciio_provider functions with a vertex. */voidpciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns){ hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns);}/* * Disassociate a set of pciio_provider functions with a vertex. */voidpciio_provider_unregister(devfs_handle_t provider){ arbitrary_info_t ainfo; hwgraph_info_remove_LBL(provider, INFO_LBL_PFUNCS, (long *) &ainfo);}/* * Obtain a pointer to the pciio_provider functions for a specified Crosstalk * provider. */pciio_provider_t *pciio_provider_fns_get(devfs_handle_t provider){ arbitrary_info_t ainfo = 0; (void) hwgraph_info_get_LBL(provider, INFO_LBL_PFUNCS, &ainfo); return (pciio_provider_t *) ainfo;}/*ARGSUSED4 */intpciio_driver_register( pciio_vendor_id_t vendor_id, pciio_device_id_t device_id, char *driver_prefix, unsigned flags){ /* a driver's init routine might call * pciio_driver_register before the * system calls pciio_init; so we * make the init call ourselves here. */ if (pciio_registry == NULL) pciio_init(); return cdl_add_driver(pciio_registry, vendor_id, device_id, driver_prefix, flags, NULL);}/* * Remove an initialization function. */voidpciio_driver_unregister( char *driver_prefix){ /* before a driver calls unregister, * it must have called register; so * we can assume we have a registry here. */ ASSERT(pciio_registry != NULL); cdl_del_driver(pciio_registry, driver_prefix, NULL);}/* * Set the slot status for a device supported by the * driver being registered. */voidpciio_driver_reg_callback( devfs_handle_t pconn_vhdl, int key1, int key2, int error){}/* * Set the slot status for a device supported by the * driver being unregistered. */voidpciio_driver_unreg_callback( devfs_handle_t pconn_vhdl, int key1, int key2, int error){}/* * Call some function with each vertex that * might be one of this driver's attach points. */voidpciio_iterate(char *driver_prefix, pciio_iter_f * func){ /* a driver's init routine might call * pciio_iterate before the * system calls pciio_init; so we * make the init call ourselves here. */ if (pciio_registry == NULL) pciio_init(); ASSERT(pciio_registry != NULL); cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func);}devfs_handle_tpciio_device_register( devfs_handle_t connectpt, /* vertex for /hw/.../pciio/%d */ devfs_handle_t master, /* card's master ASIC (PCI provider) */ pciio_slot_t slot, /* card's slot */ pciio_function_t func, /* card's func */ pciio_vendor_id_t vendor_id, pciio_device_id_t device_id){ return pciio_device_info_register (connectpt, pciio_device_info_new (NULL, master, slot, func, vendor_id, device_id));}voidpciio_device_unregister(devfs_handle_t pconn){ DEV_FUNC(pconn,device_unregister)(pconn);}pciio_info_tpciio_device_info_new( pciio_info_t pciio_info, devfs_handle_t master, pciio_slot_t slot, pciio_function_t func, pciio_vendor_id_t vendor_id, pciio_device_id_t device_id){ if (!pciio_info) NEW(pciio_info); ASSERT(pciio_info != NULL); pciio_info->c_slot = slot; pciio_info->c_func = func; pciio_info->c_vendor = vendor_id; pciio_info->c_device = device_id; pciio_info->c_master = master; pciio_info->c_mfast = hwgraph_fastinfo_get(master); pciio_info->c_pops = pciio_provider_fns_get(master); pciio_info->c_efunc = 0; pciio_info->c_einfo = 0; return pciio_info;}voidpciio_device_info_free(pciio_info_t pciio_info){ /* NOTE : pciio_info is a structure within the pcibr_info * and not a pointer to memory allocated on the heap !! */ BZERO((char *)pciio_info,sizeof(pciio_info));}devfs_handle_tpciio_device_info_register( devfs_handle_t connectpt, /* vertex at center of bus */ pciio_info_t pciio_info) /* details about the connectpt */{ char name[32]; devfs_handle_t pconn; pciio_slot_func_to_name(name, pciio_info->c_slot, pciio_info->c_func); if (GRAPH_SUCCESS != hwgraph_path_add(connectpt, name, &pconn)) return pconn; pciio_info->c_vertex = pconn; pciio_info_set(pconn, pciio_info);#ifdef BRINGUP { int pos; char dname[256]; pos = devfs_generate_path(pconn, dname, 256);#ifdef DEBUG_PCIIO printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);#endif }#endif /* BRINGUP */ /* * create link to our pci provider */ device_master_set(pconn, pciio_info->c_master);#if USRPCI /* * Call into usrpci provider to let it initialize for * the given slot. */ if (pciio_info->c_slot != PCIIO_SLOT_NONE) usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot);#endif return pconn;}voidpciio_device_info_unregister(devfs_handle_t connectpt, pciio_info_t pciio_info){ char name[32]; devfs_handle_t pconn; if (!pciio_info) return; pciio_slot_func_to_name(name, pciio_info->c_slot, pciio_info->c_func); hwgraph_edge_remove(connectpt,name,&pconn); pciio_info_set(pconn,0); /* Remove the link to our pci provider */ hwgraph_edge_remove(pconn, EDGE_LBL_MASTER, NULL); hwgraph_vertex_unref(pconn); hwgraph_vertex_destroy(pconn); }/* Add the pci card inventory information to the hwgraph */static voidpciio_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);}static voidpciio_device_inventory_remove(devfs_handle_t pconn_vhdl){#ifdef LATER hwgraph_inventory_remove(pconn_vhdl,-1,-1,-1,-1,-1);#endif}/*ARGSUSED */intpciio_device_attach(devfs_handle_t pconn, int drv_flags){ pciio_info_t pciio_info; pciio_vendor_id_t vendor_id; pciio_device_id_t device_id; int pciba_attach(devfs_handle_t); 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. */ ASSERT(pciio_registry != NULL); /* * Since pciba is not called from cdl routines .. call it here. */ pciba_attach(pconn); return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags));}intpciio_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_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 ... */voidpciio_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 */intpciio_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;}intpciio_dma_enabled(devfs_handle_t pconn_vhdl){ return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -