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

📄 pciio.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 4 页
字号:
		  unsigned flags){    return DMAMAP_FUNC(pciio_dmamap, dmamap_list)	(CAST_DMAMAP(pciio_dmamap), alenlist, flags);}voidpciio_dmamap_done(pciio_dmamap_t pciio_dmamap){    DMAMAP_FUNC(pciio_dmamap, dmamap_done)	(CAST_DMAMAP(pciio_dmamap));}iopaddr_tpciio_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */		    device_desc_t dev_desc,	/* device descriptor */		    paddr_t paddr,	/* system physical address */		    size_t byte_count,	/* length */		    unsigned flags){					/* defined in dma.h */    return DEV_FUNC(dev, dmatrans_addr)	(dev, dev_desc, paddr, byte_count, flags);}alenlist_tpciio_dmatrans_list(devfs_handle_t dev,	/* translate for this device */		    device_desc_t dev_desc,	/* device descriptor */		    alenlist_t palenlist,	/* system address/length list */		    unsigned flags){					/* defined in dma.h */    return DEV_FUNC(dev, dmatrans_list)	(dev, dev_desc, palenlist, flags);}iopaddr_tpciio_dma_addr(devfs_handle_t dev,	/* translate for this device */	       device_desc_t dev_desc,	/* device descriptor */	       paddr_t paddr,		/* system physical address */	       size_t byte_count,	/* length */	       pciio_dmamap_t *mapp,	/* map to use, then map we used */	       unsigned flags){					/* PIO flags */    pciio_dmamap_t          map = 0;    int			    errfree = 0;    iopaddr_t               res;    if (mapp) {	map = *mapp;			/* possible pre-allocated map */	*mapp = 0;			/* record "no map used" */    }    res = pciio_dmatrans_addr	(dev, dev_desc, paddr, byte_count, flags);    if (res)	return res;			/* pciio_dmatrans worked */    if (!map) {	map = pciio_dmamap_alloc	    (dev, dev_desc, byte_count, flags);	if (!map)	    return res;			/* pciio_dmamap_alloc failed */	errfree = 1;    }    res = pciio_dmamap_addr	(map, paddr, byte_count);    if (!res) {	if (errfree)	    pciio_dmamap_free(map);	return res;			/* pciio_dmamap_addr failed */    }    if (mapp)	*mapp = map;			/* pass back map used */    return res;				/* pciio_dmamap_addr succeeded */}voidpciio_dmamap_drain(pciio_dmamap_t map){    DMAMAP_FUNC(map, dmamap_drain)	(CAST_DMAMAP(map));}voidpciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size){    DEV_FUNC(dev, dmaaddr_drain)	(dev, addr, size);}voidpciio_dmalist_drain(devfs_handle_t dev, alenlist_t list){    DEV_FUNC(dev, dmalist_drain)	(dev, list);}/* ===================================================================== *          INTERRUPT MANAGEMENT * *      Allow crosstalk devices to establish interrupts *//* * Allocate resources required for an interrupt as specified in intr_desc. * Return resource handle in intr_hdl. */pciio_intr_tpciio_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */		 device_desc_t dev_desc,	/* device descriptor */		 pciio_intr_line_t lines,	/* INTR line(s) to attach */		 devfs_handle_t owner_dev){					/* owner of this interrupt */    return (pciio_intr_t) DEV_FUNC(dev, intr_alloc)	(dev, dev_desc, lines, owner_dev);}/* * Free resources consumed by intr_alloc. */voidpciio_intr_free(pciio_intr_t intr_hdl){    INTR_FUNC(intr_hdl, intr_free)	(CAST_INTR(intr_hdl));}/* * Associate resources allocated with a previous pciio_intr_alloc call with the * described handler, arg, name, etc. * * Returns 0 on success, returns <0 on failure. */intpciio_intr_connect(pciio_intr_t intr_hdl,		intr_func_t intr_func, intr_arg_t intr_arg)	/* pciio intr resource handle */{    return INTR_FUNC(intr_hdl, intr_connect)	(CAST_INTR(intr_hdl), intr_func, intr_arg);}/* * Disassociate handler with the specified interrupt. */voidpciio_intr_disconnect(pciio_intr_t intr_hdl){    INTR_FUNC(intr_hdl, intr_disconnect)	(CAST_INTR(intr_hdl));}/* * Return a hwgraph vertex that represents the CPU currently * targeted by an interrupt. */devfs_handle_tpciio_intr_cpu_get(pciio_intr_t intr_hdl){    return INTR_FUNC(intr_hdl, intr_cpu_get)	(CAST_INTR(intr_hdl));}voidpciio_slot_func_to_name(char		       *name,			pciio_slot_t		slot,			pciio_function_t	func){    /*     * standard connection points:     *     * PCIIO_SLOT_NONE:	.../pci/direct     * PCIIO_FUNC_NONE: .../pci/<SLOT>			ie. .../pci/3     * multifunction:   .../pci/<SLOT><FUNC>		ie. .../pci/3c     */    if (slot == PCIIO_SLOT_NONE)	sprintf(name, EDGE_LBL_DIRECT);    else if (func == PCIIO_FUNC_NONE)	sprintf(name, "%d", slot);    else	sprintf(name, "%d%c", slot, 'a'+func);}/* * pciio_cardinfo_get * * Get the pciio info structure corresponding to the * specified PCI "slot" (we like it when the same index * number is used for the PCI IDSEL, the REQ/GNT pair, * and the interrupt line being used for INTA. We like * it so much we call it the slot number). */static pciio_info_tpciio_cardinfo_get(		      devfs_handle_t pciio_vhdl,		      pciio_slot_t pci_slot){    char                    namebuf[16];    pciio_info_t	    info = 0;    devfs_handle_t	    conn;    pciio_slot_func_to_name(namebuf, pci_slot, PCIIO_FUNC_NONE);    if (GRAPH_SUCCESS ==	hwgraph_traverse(pciio_vhdl, namebuf, &conn)) {	info = pciio_info_chk(conn);	hwgraph_vertex_unref(conn);    }    return info;}/* * pciio_error_handler: * dispatch an error to the appropriate * pciio connection point, or process * it as a generic pci error. * Yes, the first parameter is the * provider vertex at the middle of * the bus; we get to the pciio connect * point using the ioerror widgetdev field. * * This function is called by the * specific PCI provider, after it has figured * out where on the PCI bus (including which slot, * if it can tell) the error came from. *//*ARGSUSED */intpciio_error_handler(		       devfs_handle_t pciio_vhdl,		       int error_code,		       ioerror_mode_t mode,		       ioerror_t *ioerror){    pciio_info_t            pciio_info;    devfs_handle_t            pconn_vhdl;#if USRPCI    devfs_handle_t            usrpci_v;#endif    pciio_slot_t            slot;    int                     retval;#ifdef EHE_ENABLE    error_state_t	    e_state;#endif /* EHE_ENABLE */#if DEBUG && ERROR_DEBUG    printk("%v: pciio_error_handler\n", pciio_vhdl);#endif    IOERR_PRINTF(printk(KERN_NOTICE "%v: PCI Bus Error: Error code: %d Error mode: %d\n",			 pciio_vhdl, error_code, mode));    /* If there is an error handler sitting on     * the "no-slot" connection point, give it     * first crack at the error. NOTE: it is     * quite possible that this function may     * do further refining of the ioerror.     */    pciio_info = pciio_cardinfo_get(pciio_vhdl, PCIIO_SLOT_NONE);    if (pciio_info && pciio_info->c_efunc) {	pconn_vhdl = pciio_info_dev_get(pciio_info);#ifdef EHE_ENABLE	e_state = error_state_get(pciio_vhdl);	if (e_state == ERROR_STATE_ACTION)	    (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);	if (error_state_set(pconn_vhdl,e_state) == ERROR_RETURN_CODE_CANNOT_SET_STATE)	    return(IOERROR_UNHANDLED);#endif 	retval = pciio_info->c_efunc	    (pciio_info->c_einfo, error_code, mode, ioerror);	if (retval != IOERROR_UNHANDLED)	    return retval;    }    /* Is the error associated with a particular slot?     */    if (IOERROR_FIELDVALID(ioerror, widgetdev)) {	short widgetdev;	/*	 * NOTE : 	 * widgetdev is a 4byte value encoded as slot in the higher order	 * 2 bytes and function in the lower order 2 bytes.	 */	IOERROR_GETVALUE(widgetdev, ioerror, widgetdev);	slot = pciio_widgetdev_slot_get(widgetdev);	/* If this slot has an error handler,	 * 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);#ifdef EHE_ENABLE		e_state = error_state_get(pciio_vhdl);		if (e_state == ERROR_STATE_ACTION)		    (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);		if (error_state_set(pconn_vhdl,e_state) ==		    ERROR_RETURN_CODE_CANNOT_SET_STATE)		    return(IOERROR_UNHANDLED);#endif /* EHE_ENABLE */		retval = pciio_info->c_efunc		    (pciio_info->c_einfo, error_code, mode, ioerror);		if (retval != IOERROR_UNHANDLED)		    return retval;	    }#if USRPCI	    /* If the USRPCI driver is available and	     * knows about this connection point,	     * deliver the error to it.	     *	     * OK to use pconn_vhdl here, even though we	     * have already UNREF'd it, since we know that	     * it is not going away.	     */	    pconn_vhdl = pciio_info_dev_get(pciio_info);	    if (GRAPH_SUCCESS == hwgraph_traverse(pconn_vhdl, EDGE_LBL_USRPCI, &usrpci_v)) {		iopaddr_t busaddr;		IOERROR_GETVALUE(busaddr, ioerror, busaddr);		retval = usrpci_error_handler (usrpci_v, error_code, busaddr);		hwgraph_vertex_unref(usrpci_v);		if (retval != IOERROR_UNHANDLED) {		    /*		     * This unref is not needed.  If this code is called often enough,		     * the system will crash, due to vertex reference count reaching 0,		     * causing vertex to be unallocated.  -jeremy		     * hwgraph_vertex_unref(pconn_vhdl);		     */		    return retval;		}	    }#endif	}    }    return (mode == MODE_DEVPROBE)	? IOERROR_HANDLED	/* probes are OK */	: IOERROR_UNHANDLED;	/* otherwise, foo! */}/* ===================================================================== *          CONFIGURATION MANAGEMENT *//* * Startup a crosstalk provider */voidpciio_provider_startup(devfs_handle_t pciio_provider){    DEV_FUNC(pciio_provider, provider_startup)	(pciio_provider);}/* * Shutdown a crosstalk provider */voidpciio_provider_shutdown(devfs_handle_t pciio_provider){    DEV_FUNC(pciio_provider, provider_shutdown)	(pciio_provider);}/* * Specify endianness constraints.  The driver tells us what the device * does and how it would like to see things in memory.  We reply with * how things will actually appear in memory. */pciio_endian_tpciio_endian_set(devfs_handle_t dev,		 pciio_endian_t device_end,		 pciio_endian_t desired_end){    ASSERT((device_end == PCIDMA_ENDIAN_BIG) || (device_end == PCIDMA_ENDIAN_LITTLE));    ASSERT((desired_end == PCIDMA_ENDIAN_BIG) || (desired_end == PCIDMA_ENDIAN_LITTLE));#if DEBUG#if defined(SUPPORT_PRINTING_V_FORMAT)    printk(KERN_ALERT  "%v: pciio_endian_set is going away.\n"	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",	    dev);#else    printk(KERN_ALERT  "0x%x: pciio_endian_set is going away.\n"	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",	    dev);#endif#endif    return DEV_FUNC(dev, endian_set)	(dev, device_end, desired_end);}/* * Specify PCI arbitration priority. */pciio_priority_tpciio_priority_set(devfs_handle_t dev,		   pciio_priority_t device_prio){    ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW));    return DEV_FUNC(dev, priority_set)	(dev, device_prio);}/* * Read value of configuration register */uint64_tpciio_config_get(devfs_handle_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(devfs_handle_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)

⌨️ 快捷键说明

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