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

📄 io.c

📁 上传linux-jx2410的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
 * address range. *//* ARGSUSED */extern iopaddr_thub_dmamap_addr(	hub_dmamap_t dmamap,	/* use these mapping resources */			paddr_t paddr,		/* map for this address */			size_t byte_count)	/* map this many bytes */{	devfs_handle_t vhdl;	ASSERT(dmamap->hdma_flags & HUB_DMAMAP_IS_VALID);	if (dmamap->hdma_flags & HUB_DMAMAP_USED) {	    /* If the map is FIXED, re-use is OK. */	    if (!(dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {		vhdl = dmamap->hdma_xtalk_info.xd_dev;#if defined(SUPPORT_PRINTING_V_FORMAT)		PRINT_WARNING("%v: hub_dmamap_addr re-uses dmamap.\n",vhdl);#else		PRINT_WARNING("0x%x: hub_dmamap_addr re-uses dmamap.\n", vhdl);#endif	    }	} else {		dmamap->hdma_flags |= HUB_DMAMAP_USED;	}	/* There isn't actually any DMA mapping hardware on the hub. */	return(paddr);}/* * Establish a DMA mapping using the resources allocated in a previous dmamap_alloc. * Return an appropriate crosstalk address list that maps to the specified physical  * address list. *//* ARGSUSED */alenlist_thub_dmamap_list(hub_dmamap_t hub_dmamap,	/* use these mapping resources */		alenlist_t palenlist,		/* map this area of memory */		unsigned flags){	devfs_handle_t vhdl;	ASSERT(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_VALID);	if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) {	    /* If the map is FIXED, re-use is OK. */	    if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {		vhdl = hub_dmamap->hdma_xtalk_info.xd_dev;#if defined(SUPPORT_PRINTING_V_FORMAT)		PRINT_WARNING("%v: hub_dmamap_list re-uses dmamap\n",vhdl);#else		PRINT_WARNING("0x%x: hub_dmamap_list re-uses dmamap\n", vhdl);#endif	    }	} else {		hub_dmamap->hdma_flags |= HUB_DMAMAP_USED;	}	/* There isn't actually any DMA mapping hardware on the hub.  */	return(palenlist);}/* * Driver indicates that it has completed whatever DMA it may have started * after an earlier dmamap_addr or dmamap_list call. */voidhub_dmamap_done(hub_dmamap_t hub_dmamap)	/* done with these mapping resources */{	devfs_handle_t vhdl;	if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) {		hub_dmamap->hdma_flags &= ~HUB_DMAMAP_USED;	} else {	    /* If the map is FIXED, re-done is OK. */	    if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {		vhdl = hub_dmamap->hdma_xtalk_info.xd_dev;#if defined(SUPPORT_PRINTING_V_FORMAT)		PRINT_WARNING("%v: hub_dmamap_done already done with dmamap\n",vhdl);#else		PRINT_WARNING("0x%x: hub_dmamap_done already done with dmamap\n", vhdl);#endif	    }	}}/* * Translate a single system physical address into a crosstalk address. *//* ARGSUSED */iopaddr_thub_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 */{	/* no translation needed */	return(paddr);}/* * Translate a list of IP27 addresses and lengths into a list of crosstalk  * addresses and lengths.  No actual hardware mapping takes place; the hub  * has no DMA mapping registers -- crosstalk addresses map directly. *//* ARGSUSED */alenlist_thub_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 */{	/* no translation needed */	return(palenlist);}/*ARGSUSED*/voidhub_dmamap_drain(	hub_dmamap_t map){    /* XXX- flush caches, if cache coherency WAR is needed */}/*ARGSUSED*/voidhub_dmaaddr_drain(	devfs_handle_t vhdl,			paddr_t addr,			size_t bytes){    /* XXX- flush caches, if cache coherency WAR is needed */}/*ARGSUSED*/voidhub_dmalist_drain(	devfs_handle_t vhdl,			alenlist_t list){    /* XXX- flush caches, if cache coherency WAR is needed */}/* INTERRUPT MANAGEMENT *//* ARGSUSED */static voidhub_intr_init(devfs_handle_t hubv){}/* * hub_device_desc_update *	Update the passed in device descriptor with the actual the * 	target cpu number and interrupt priority level. *	NOTE : These might be the same as the ones passed in thru *	the descriptor. */static voidhub_device_desc_update(device_desc_t 	dev_desc, 		       ilvl_t 		intr_swlevel,		       cpuid_t		cpu){	char	cpuname[40];		/* Store the interrupt priority level in the device descriptor */	device_desc_intr_swlevel_set(dev_desc, intr_swlevel);	/* Convert the cpuid to the vertex handle in the hwgraph and	 * save it in the device descriptor.	 */	sprintf(cpuname,"/hw/cpunum/%ld",cpu);	device_desc_intr_target_set(dev_desc, 				    hwgraph_path_to_dev(cpuname));}int allocate_my_bit = INTRCONNECT_ANYBIT;/* * Allocate resources required for an interrupt as specified in dev_desc. * Returns a hub interrupt handle on success, or 0 on failure. */static hub_intr_tdo_hub_intr_alloc(devfs_handle_t dev,		/* which crosstalk device */		  device_desc_t dev_desc,	/* device descriptor */		  devfs_handle_t owner_dev,	/* owner of this interrupt, if known */		  int uncond_nothread)		/* unconditionally non-threaded */{	cpuid_t cpu = (cpuid_t)0;			/* cpu to receive interrupt */        int cpupicked = 0;	int bit;			/* interrupt vector */	/*REFERENCED*/	int intr_resflags = 0;	hub_intr_t intr_hdl;	cnodeid_t nodeid;		/* node to receive interrupt */	/*REFERENCED*/	nasid_t nasid;			/* nasid to receive interrupt */	struct xtalk_intr_s *xtalk_info;	iopaddr_t xtalk_addr;		/* xtalk addr on hub to set intr */	xwidget_info_t xwidget_info;	/* standard crosstalk widget info handle */	char *intr_name = NULL;	ilvl_t intr_swlevel;	extern int default_intr_pri;#ifdef CONFIG_IA64_SGI_SN1 	extern void synergy_intr_alloc(int, int);#endif		/*	 * If caller didn't explicily specify a device descriptor, see if there's	 * a default descriptor associated with the device.	 */	if (!dev_desc) 		dev_desc = device_desc_default_get(dev);	if (dev_desc) {		intr_name = device_desc_intr_name_get(dev_desc);		intr_swlevel = device_desc_intr_swlevel_get(dev_desc);		if (dev_desc->flags & D_INTR_ISERR) {			intr_resflags = II_ERRORINT;		} else if (!uncond_nothread && !(dev_desc->flags & D_INTR_NOTHREAD)) {			intr_resflags = II_THREADED;		} else {			/* Neither an error nor a thread. */			intr_resflags = 0;		}	} else {		intr_swlevel = default_intr_pri;		if (!uncond_nothread)			intr_resflags = II_THREADED;	}	/* XXX - Need to determine if the interrupt should be threaded. */	/* If the cpu has not been picked already then choose a candidate 	 * interrupt target and reserve the interrupt bit 	 */#if defined(NEW_INTERRUPTS)	if (!cpupicked) {		cpu = intr_heuristic(dev,dev_desc,allocate_my_bit,				     intr_resflags,owner_dev,				     intr_name,&bit);	}#endif	/* At this point we SHOULD have a valid cpu */	if (cpu == CPU_NONE) {#if defined(SUPPORT_PRINTING_V_FORMAT)		PRINT_WARNING("%v hub_intr_alloc could not allocate interrupt\n",			owner_dev);#else		PRINT_WARNING("0x%x hub_intr_alloc could not allocate interrupt\n",			owner_dev);#endif		return(0);	}	/* If the cpu has been picked already (due to the bridge data 	 * corruption bug) then try to reserve an interrupt bit .	 */#if defined(NEW_INTERRUPTS)	if (cpupicked) {		bit = intr_reserve_level(cpu, allocate_my_bit, 					 intr_resflags, 					 owner_dev, intr_name);		if (bit < 0) {#if defined(SUPPORT_PRINTING_V_FORMAT)			PRINT_WARNING("Could not reserve an interrupt bit for cpu "				" %d and dev %v\n",				cpu,owner_dev);#else			PRINT_WARNING("Could not reserve an interrupt bit for cpu "				" %d and dev 0x%x\n",				cpu, owner_dev);#endif							return(0);		}	}#endif	/* NEW_INTERRUPTS */	nodeid = cpuid_to_cnodeid(cpu);	nasid = cpuid_to_nasid(cpu);	xtalk_addr = HUBREG_AS_XTALKADDR(nasid, PIREG(PI_INT_PEND_MOD, cpuid_to_subnode(cpu)));	/*	 * Allocate an interrupt handle, and fill it in.  There are two	 * pieces to an interrupt handle: the piece needed by generic	 * xtalk code which is used by crosstalk device drivers, and	 * the piece needed by low-level IP27 hardware code.	 */	intr_hdl = kmem_alloc_node(sizeof(struct hub_intr_s), KM_NOSLEEP, nodeid);	ASSERT_ALWAYS(intr_hdl);	/* 	 * Fill in xtalk information for generic xtalk interfaces that	 * operate on xtalk_intr_hdl's.	 */	xtalk_info = &intr_hdl->i_xtalk_info;	xtalk_info->xi_dev = dev;	xtalk_info->xi_vector = bit;	xtalk_info->xi_addr = xtalk_addr;	/*	 * Regardless of which CPU we ultimately interrupt, a given crosstalk	 * widget always handles interrupts (and PIO and DMA) through its 	 * designated "master" crosstalk provider.	 */	xwidget_info = xwidget_info_get(dev);	if (xwidget_info)		xtalk_info->xi_target = xwidget_info_masterid_get(xwidget_info);	/* Fill in low level hub information for hub_* interrupt interface */	intr_hdl->i_swlevel = intr_swlevel;	intr_hdl->i_cpuid = cpu;	intr_hdl->i_bit = bit;	intr_hdl->i_flags = HUB_INTR_IS_ALLOCED;	/* Store the actual interrupt priority level & interrupt target	 * cpu back in the device descriptor.	 */	hub_device_desc_update(dev_desc, intr_swlevel, cpu);#ifdef CONFIG_IA64_SGI_SN1	synergy_intr_alloc((int)bit, (int)cpu);#endif	return(intr_hdl);}/* * Allocate resources required for an interrupt as specified in dev_desc. * Returns a hub interrupt handle on success, or 0 on failure. */hub_intr_thub_intr_alloc(	devfs_handle_t dev,		/* which crosstalk device */		device_desc_t dev_desc,		/* device descriptor */		devfs_handle_t owner_dev)		/* owner of this interrupt, if known */{	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 0));}/* * Allocate resources required for an interrupt as specified in dev_desc. * Uncondtionally request non-threaded, regardless of what the device * descriptor might say. * Returns a hub interrupt handle on success, or 0 on failure. */hub_intr_thub_intr_alloc_nothd(devfs_handle_t dev,		/* which crosstalk device */		device_desc_t dev_desc,		/* device descriptor */		devfs_handle_t owner_dev)		/* owner of this interrupt, if known */{	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 1));}/* * Free resources consumed by intr_alloc. */voidhub_intr_free(hub_intr_t intr_hdl){	cpuid_t cpu = intr_hdl->i_cpuid;	int bit = intr_hdl->i_bit;	xtalk_intr_t xtalk_info;	if (intr_hdl->i_flags & HUB_INTR_IS_CONNECTED) {		/* Setting the following fields in the xtalk interrupt info	 	 * clears the interrupt target register in the xtalk user	 	 */		xtalk_info = &intr_hdl->i_xtalk_info;		xtalk_info->xi_dev = NODEV;		xtalk_info->xi_vector = 0;		xtalk_info->xi_addr = 0;		hub_intr_disconnect(intr_hdl);	}	if (intr_hdl->i_flags & HUB_INTR_IS_ALLOCED)		kfree(intr_hdl);#if defined(NEW_INTERRUPTS)	intr_unreserve_level(cpu, bit);#endif}/* * Associate resources allocated with a previous hub_intr_alloc call with the * described handler, arg, name, etc. *//*ARGSUSED*/inthub_intr_connect(	hub_intr_t intr_hdl,		/* xtalk intr resource handle */			intr_func_t intr_func,		/* xtalk intr handler */			void *intr_arg,			/* arg to intr handler */			xtalk_intr_setfunc_t setfunc,	/* func to set intr hw */			void *setfunc_arg,		/* arg to setfunc */			void *thread)			/* intr thread to use */{	int rv;	cpuid_t cpu = intr_hdl->i_cpuid;	int bit = intr_hdl->i_bit;#ifdef CONFIG_IA64_SGI_SN1	extern int synergy_intr_connect(int, int);#endif	ASSERT(intr_hdl->i_flags & HUB_INTR_IS_ALLOCED);#if defined(NEW_INTERRUPTS)	rv = intr_connect_level(cpu, bit, intr_hdl->i_swlevel, 					intr_func, intr_arg, NULL);	if (rv < 0)		return(rv);#endif	intr_hdl->i_xtalk_info.xi_setfunc = setfunc;	intr_hdl->i_xtalk_info.xi_sfarg = setfunc_arg;	if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl);	intr_hdl->i_flags |= HUB_INTR_IS_CONNECTED;#ifdef CONFIG_IA64_SGI_SN1	return(synergy_intr_connect((int)bit, (int)cpu));#endif}/* * Disassociate handler with the specified interrupt. */voidhub_intr_disconnect(hub_intr_t intr_hdl){	/*REFERENCED*/	int rv;	cpuid_t cpu = intr_hdl->i_cpuid;	int bit = intr_hdl->i_bit;	xtalk_intr_setfunc_t setfunc;	setfunc = intr_hdl->i_xtalk_info.xi_setfunc;

⌨️ 快捷键说明

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