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

📄 pd6700.c

📁 周立功magic2410实验箱源码 第6章Linux高级实验(part1) 6.1 Linux内核编译实验 6.2 Linux根文件系统实验 6.3 CAT1025读/写实验. 6.4 ZL
💻 C
📖 第 1 页 / 共 5 页
字号:
{    socket[sockets].ioaddr = port;									// CPU与接口控制器地址    socket[sockets].psock = psock;									// 接口偏移    socket[sockets].type = type;										// 控制器类型    socket[sockets].flags = pcic[type].flags;				// 标记接口桥类型    if (is_alive(sockets))													// 查询当前接口是否活动的,已被使用				socket[sockets].flags |= IS_ALIVE;						// 接口是活动的    sockets++;																	// 系统接口数加1}/*********************************************************************************************************** Function name: add_pcmcia_bridge** Descriptions: 添加PCMCIA桥接口处理函数,仅在ini_pcmcia_bridge()函数中被使用** Input: ns , 接口数**				type ,接口类型** Output :** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static void __init add_pcmcia_bridge(int ns, int type){    u_int mask = 0, i, base;    socket_info_t *t = &socket[sockets-ns];		// 接口描述数据结构    base = sockets-ns;												// 系统当前操作接口序号    if (t->ioaddr > 0)     		request_region(t->ioaddr, 2, "pd6700");		// 申请IO地址    if (base == 0) printk("\n");    printk(KERN_INFO "  %s", pcic[type].name);										// 打印接口名称    printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x", t->ioaddr, t->psock*0x40);    printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : ""));    set_bridge_opts(base, ns);    if (!cs_irq) {										// 如果不使用硬件中断就用定时器查询				if (poll_interval == 0)  poll_interval = HZ;				printk(" polling interval = %d ms\n",  poll_interval * 1000 / HZ);    }    /* Update socket interrupt information, capabilities */    // 与硬件系统相关的初始化    for (i = 0; i < ns; i++) {				/* Use SS_CAP_STATIC_MAP which disables the memory resource				   database check and SS_CAP_PAGE_REGS which disable io port 				   maximun limit 0xffff */				t[i].cap.features |= SS_CAP_PCCARD | SS_CAP_STATIC_MAP | SS_CAP_PAGE_REGS;				/* We just pass up an offset which is applied to client-requested 				   base I/O addresses in alloc_io_space() */				t[i].cap.io_offset = vCF_IO_BASE;		// IO基地址				/* Map Size */				t[i].cap.map_size = 0x1000;					// IO地址范围				/* Do not use ISA irq */				t[i].cap.irq_mask = 0;				t[i].cap.pci_irq = IRQ_CF_RDY;			// 卡上中断				/* Card Detect IRQ */				t[i].cs_irq = cs_irq;							// 卡检测中断				/* Enable Management Interrupt for card detect */				t[i].intr = PD67_INTR_ENA;					// 使能卡检测中断				/* PD6710 IRQ3 is only connected to IRQ_CF_RDY */				t[i].intr |= 3 << 0;								// 卡中断    }} /* add_pcmcia_bridge *//*********************************************************************************************************** Function name: ini_pcmcia_bridge** Descriptions: 初始化PCMCIA桥芯片,并分配系统硬件资源,仅在init_pd6700()函数中使用.** Input: 无** Output : 无** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static void __init ini_pcmcia_bridge(void){    int id;    if (check_region(pd67_base, 2) != 0) {							// 检查基地址是否被使用				if (sockets == 0)   printk("port conflict at %#x\n", pd67_base);				return;    }    id = identify(pd67_base, 0);												// 识别芯片ID PD6710返回08		if( id == -1)			return;																	// 芯片不存在或无法识别		add_socket(pd67_base, 0, id);			// 添加1个PCMCIA接口		if(id == IS_PD6710)		add_pcmcia_bridge(1, id);									// 添加设备到系统		if(id == IS_PD6722)		add_pcmcia_bridge(2, id);									// 添加设备到系统}/*====================================================================*/static u_int pending_events[8];static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;/*********************************************************************************************************** Function name: pcic_bh** Descriptions: 中断下半部处理函数** Input:** Output :** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static void pcic_bh(void *dummy){	u_int events;	int i;	for (i=0; i < sockets; i++) {		spin_lock_irq(&pending_event_lock);		// 禁止本地中断并获取指定的锁		events = pending_events[i];						// 获取处理事件		pending_events[i] = 0;								// 清零事件		spin_unlock_irq(&pending_event_lock);	// 释放指定的锁,并激活本地中断		/* 		SS_DETECT events need a small delay here. The reason for this is that 		the "is there a card" electronics need time to see the card after the		"we have a card coming in" electronics have seen it. 		*/		if (events & SS_DETECT) 	// 检测到卡插入,需延迟一定时间,直到卡内部工作稳定			mdelay(4);		if (socket[i].handler)			socket[i].handler(socket[i].info, events);	// 调用接口事件处理函数	}}static struct tq_struct pcic_task = {	routine:	pcic_bh};static unsigned long last_detect_jiffies;/*********************************************************************************************************** Function name: pcic_interrupt** Descriptions: PCMCIA卡中断服务程序** Input: irq, 中断号**			  *dev,**				*regs,** Output : 无** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static void pcic_interrupt(int irq, void *dev, struct pt_regs *regs){    int i, j, csc;    u_int events, active;    u_long flags = 0;    for (j = 0; j < 20; j++) {				active = 0;				for (i = 0; i < sockets; i++) {				    if ((socket[i].cs_irq != irq) &&								(socket[i].cap.pci_irq != irq))									continue;																	// 非本接口中断				    ISA_LOCK(i, flags);				    csc = pd67_get(i, PD67_CSC);									// 读取状态寄存器				    if ((csc == 0) || (!socket[i].handler) || 		// 事件处理句柄为空								(pd67_get(i, PD67_IDENT) & 0x70)) {							// 未知控制器,PD6710的位4~5为0								ISA_UNLOCK(i, flags);								continue;											// 非本接口中断				    }				    events = (csc & PD67_CSC_DETECT) ? SS_DETECT : 0;			// 记录事件,卡状态改变				    				    				    /* Several sockets will send multiple "new card detected"				       events in rapid succession. However, the rest of the pcmcia expects 				       only one such event. We just ignore these events by having a			               timeout */							    if (events) {				    	if ((jiffies - last_detect_jiffies)<(HZ/20)) 		// 超时,忽略中断				    		events = 0;				    	last_detect_jiffies = jiffies;				    					    }								    if (pd67_get(i, PD67_INTCTL) & PD67_PC_IOCARD)										events |= (csc & PD67_CSC_STSCHG) ? SS_STSCHG : 0;	// IO卡模式				    else {								events |= (csc & PD67_CSC_BVD1) ? SS_BATDEAD : 0;								events |= (csc & PD67_CSC_BVD2) ? SS_BATWARN : 0;								events |= (csc & PD67_CSC_READY) ? SS_READY : 0;				    }				    ISA_UNLOCK(i, flags);				    DEBUG(2, "pd6700: socket %d event 0x%02x\n", i, events);							    if (events) {					    spin_lock(&pending_event_lock);					// 					    pending_events[i] |= events;						// 					    spin_unlock(&pending_event_lock);				// 					    schedule_task(&pcic_task);							// 下半部处理				    }				    active |= events;				}//end for(i = 0; i < sockets; i++)				if (!active) break;    }// end for (j = 0; j < 20; j++)    if (j == 20)				printk(KERN_NOTICE "pd6700: infinite loop in interrupt handler\n");    DEBUG(4, "pd6700: interrupt done\n");} /* pcic_interrupt *//*********************************************************************************************************** Function name: pcic_interrupt_wrapper** Descriptions: 通过使用定时器轮询中断** Input: data ,不使用** Output : 无** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static void pcic_interrupt_wrapper(u_long data){    pcic_interrupt(0, NULL, NULL);    poll_timer.expires = jiffies + poll_interval;    add_timer(&poll_timer);}/*====================================================================*//*********************************************************************************************************** Function name: pd67_register_callback** Descriptions: 注册回调函数.当有事件产生时,通过调用handler函数解析。** Input: sock,接口号**				*handler,事件处理函数**				* info, ** Output :** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************///注册回调函数static int pd67_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info){    socket[sock].handler = handler;				// 事件解析处理函数    socket[sock].info = info;							//     if (handler == NULL) {				MOD_DEC_USE_COUNT;    } else {				MOD_INC_USE_COUNT;    }    return 0;} /* pd67_register_callback *//*====================================================================*//*********************************************************************************************************** Function name: pd67_inquire_socket** Descriptions: 查询PCMCIA接口的能力,设备驱都需要得知PCMCIA接口的所能提供的资源。** Input: sock, 接口索引**			  cap, 描述能力信息数据结构指针** Output : 0** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static int pd67_inquire_socket(unsigned int sock, socket_cap_t *cap){    *cap = socket[sock].cap;    return 0;} /* pd67_inquire_socket *//*====================================================================*//*********************************************************************************************************** Function name: pd67_get_status** Descriptions: 获取接口当前状态,主要是状态寄存器的一些值** Input: sock, 接口索引**			  *value, 返回的状态值** Output : 返回0** Created by:** Created Date: **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/static int pd67_get_status(unsigned int sock, u_int *value){    u_int status;    		if (socket[sock].flags & IS_ALIVE)				return -EINVAL;		    status = pd67_get(sock, PD67_STATUS);    *value = ((status & PD67_CS_DETECT) == PD67_CS_DETECT)	? SS_DETECT : 0;	    if (pd67_get(sock, PD67_INTCTL) & PD67_PC_IOCARD)				*value |= (status & PD67_CS_STSCHG) ? 0 : SS_STSCHG;		// IO卡    else {				*value |= (status & PD67_CS_BVD1) ? 0 : SS_BATDEAD;			// 非IO卡				*value |= (status & PD67_CS_BVD2) ? 0 : SS_BATWARN;    }    *value |= (status & PD67_CS_WRPROT) ? SS_WRPROT : 0;    *value |= (status & PD67_CS_READY) ? SS_READY : 0;    *value |= (status & PD67_CS_POWERON) ? SS_POWERON : 0;        DEBUG(1, "pd6700: GetStatus(%d) = %#4.4x\n", sock, *value);    return 0;} /* pd67_get_status *//*====================================================================*//*********************************************************************************************************

⌨️ 快捷键说明

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