⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pciio.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * deliver the error to it.	 */	pciio_info = pciio_cardinfo_get(pciio_vhdl, slot);	if (pciio_info != NULL) {	    if (pciio_info->c_efunc != NULL) {		pconn_vhdl = pciio_info_dev_get(pciio_info);		retval = pciio_info->c_efunc		    (pciio_info->c_einfo, error_code, mode, ioerror);		if (retval != IOERROR_UNHANDLED)		    return retval;	    }	}    }    return (mode == MODE_DEVPROBE)	? IOERROR_HANDLED	/* probes are OK */	: IOERROR_UNHANDLED;	/* otherwise, foo! */}/* ===================================================================== *          CONFIGURATION MANAGEMENT *//* * Startup a crosstalk provider */voidpciio_provider_startup(vertex_hdl_t pciio_provider){    DEV_FUNC(pciio_provider, provider_startup)	(pciio_provider);}/* * Shutdown a crosstalk provider */voidpciio_provider_shutdown(vertex_hdl_t pciio_provider){    DEV_FUNC(pciio_provider, provider_shutdown)	(pciio_provider);}/* * Read value of configuration register */uint64_tpciio_config_get(vertex_hdl_t	dev,		 unsigned	reg,		 unsigned	size){    uint64_t	value = 0;    unsigned	shift = 0;    /* handle accesses that cross words here,     * since that's common code between all     * possible providers.     */    while (size > 0) {	unsigned	biw = 4 - (reg&3);	if (biw > size)	    biw = size;	value |= DEV_FUNC(dev, config_get)	    (dev, reg, biw) << shift;	shift += 8*biw;	reg += biw;	size -= biw;    }    return value;}/* * Change value of configuration register */voidpciio_config_set(vertex_hdl_t	dev,		 unsigned	reg,		 unsigned	size,		 uint64_t	value){    /* handle accesses that cross words here,     * since that's common code between all     * possible providers.     */    while (size > 0) {	unsigned	biw = 4 - (reg&3);	if (biw > size)	    biw = size;	    	DEV_FUNC(dev, config_set)	    (dev, reg, biw, value);	reg += biw;	size -= biw;	value >>= biw * 8;    }}/* ===================================================================== *          GENERIC PCI SUPPORT FUNCTIONS *//* * Issue a hardware reset to a card. */intpciio_reset(vertex_hdl_t dev){    return DEV_FUNC(dev, reset) (dev);}/****** Generic pci slot information interfaces ******/pciio_info_tpciio_info_chk(vertex_hdl_t pciio){    arbitrary_info_t        ainfo = 0;    hwgraph_info_get_LBL(pciio, INFO_LBL_PCIIO, &ainfo);    return (pciio_info_t) ainfo;}pciio_info_tpciio_info_get(vertex_hdl_t pciio){    pciio_info_t            pciio_info;    pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio);#ifdef DEBUG_PCIIO    {	int pos;	char dname[256];	pos = devfs_generate_path(pciio, dname, 256);	printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);    }#endif /* DEBUG_PCIIO */    if ((pciio_info != NULL) &&        (pciio_info->c_fingerprint != pciio_info_fingerprint)        && (pciio_info->c_fingerprint != NULL)) {        return((pciio_info_t)-1); /* Should panic .. */    }    return pciio_info;}voidpciio_info_set(vertex_hdl_t pciio, pciio_info_t pciio_info){    if (pciio_info != NULL)	pciio_info->c_fingerprint = pciio_info_fingerprint;    hwgraph_fastinfo_set(pciio, (arbitrary_info_t) pciio_info);    /* Also, mark this vertex as a PCI slot     * and use the pciio_info, so pciio_info_chk     * can work (and be fairly efficient).     */    hwgraph_info_add_LBL(pciio, INFO_LBL_PCIIO,			 (arbitrary_info_t) pciio_info);}vertex_hdl_tpciio_info_dev_get(pciio_info_t pciio_info){    return (pciio_info->c_vertex);}pciio_slot_tpciio_info_slot_get(pciio_info_t pciio_info){    return (pciio_info->c_slot);}vertex_hdl_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);}/* ===================================================================== *          GENERIC PCI INITIALIZATION FUNCTIONS *//* *    pciioattach: called for each vertex in the graph *      that is a PCI provider. *//*ARGSUSED */intpciio_attach(vertex_hdl_t pciio){#if DEBUG && ATTACH_DEBUG    char devname[MAXDEVNAME];    printk("%s: pciio_attach\n", vertex_to_name(pciio, devname, MAXDEVNAME));#endif    return 0;}/* * Associate a set of pciio_provider functions with a vertex. */voidpciio_provider_register(vertex_hdl_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(vertex_hdl_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(vertex_hdl_t provider){    arbitrary_info_t        ainfo = 0;    (void) hwgraph_info_get_LBL(provider, INFO_LBL_PFUNCS, &ainfo);    return (pciio_provider_t *) ainfo;}pciio_info_tpciio_device_info_new(		pciio_info_t pciio_info,		vertex_hdl_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 !!     */    memset((char *)pciio_info, 0, sizeof(pciio_info));}vertex_hdl_tpciio_device_info_register(		vertex_hdl_t connectpt,		/* vertex at center of bus */		pciio_info_t pciio_info)	/* details about the connectpt */{    char		name[32];    vertex_hdl_t	pconn;    int device_master_set(vertex_hdl_t, vertex_hdl_t);    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 DEBUG_PCIIO    {	int pos;	char dname[256];	pos = devfs_generate_path(pconn, dname, 256);	printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);    }#endif /* DEBUG_PCIIO */    /*     * create link to our pci provider     */    device_master_set(pconn, pciio_info->c_master);    return pconn;}voidpciio_device_info_unregister(vertex_hdl_t connectpt,			     pciio_info_t pciio_info){    char		name[32];    vertex_hdl_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(vertex_hdl_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 */intpciio_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));}intpciio_device_detach(vertex_hdl_t pconn,		    int          drv_flags){    return(0);}/* * Allocate space from the specified PCI window mapping resource.  On * success record information about the allocation in the supplied window * allocation cookie (if non-NULL) and return the address of the allocated * window.  On failure return NULL. * * The "size" parameter is usually from a PCI device's Base Address Register * (BAR) decoder.  As such, the allocation must be aligned to be a multiple of * that.  The "align" parameter acts as a ``minimum alignment'' allocation * constraint.  The alignment contraint reflects system or device addressing * restrictions such as the inability to share higher level ``windows'' * between devices, etc.  The returned PCI address allocation will be a * multiple of the alignment constraint both in alignment and size.  Thus, the * returned PCI address block is aligned to the maximum of the requested size * and alignment. */iopaddr_tpciio_device_win_alloc(struct resource *root_resource,		       pciio_win_alloc_t win_alloc,		       size_t start, size_t size, size_t align){	struct resource *new_res;	int status = 0;	new_res = (struct resource *) kmalloc( sizeof(struct resource), GFP_KERNEL);	if (start > 0) {		status = allocate_resource( root_resource, new_res,			size, start /* Min start addr. */,			(start + size) - 1, 1,			NULL, NULL);	} else {		if (size > align)			align = size;		status = allocate_resource( root_resource, new_res,				    size, align /* Min start addr. */,				    root_resource->end, align,				    NULL, NULL);	}	if (status) {		kfree(new_res);		return((iopaddr_t) NULL);	}	/*	 * If a window allocation cookie has been supplied, use it to keep	 * track of all the allocated space assigned to this window.	 */	if (win_alloc) {		win_alloc->wa_resource = new_res;		win_alloc->wa_base = new_res->start;		win_alloc->wa_pages = size;	}	return new_res->start;;}/* * Free the specified window allocation back into the PCI window mapping * resource.  As noted above, we keep page addresses offset by 1 ... */voidpciio_device_win_free(pciio_win_alloc_t win_alloc){	int status = 0;	if (win_alloc->wa_resource) {		status = release_resource(win_alloc->wa_resource);		if (!status)			kfree(win_alloc->wa_resource);		else			BUG();	}}/* * 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(vertex_hdl_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(vertex_hdl_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(vertex_hdl_t pconn_vhdl){	return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl);}intpciio_info_type1_get(pciio_info_t pci_info){	return(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -