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

📄 eicon_io.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
						break;					  case 0:						ram_outb(ccard, &ReqOut->ReqId, chan->e.B2Id); 						break;					  case 2:						ep = &chan->be;						break;					}					tmpid = chan->e.B2Id;					chan->e.ReqCh = 1;					if (((reqbuf->Req & 0x0f) == 0x08) ||					   ((reqbuf->Req & 0x0f) == 0x01)) { /* Send Data */						chan->waitq = reqbuf->XBuffer.length;						chan->waitpq += reqbuf->XBuffer.length;						dlev = 128;					}				}			} else {	/* It is an ASSIGN */				switch(scom) {				  case 1:					ram_outb(ccard, &com->ReqId, reqbuf->ReqId); 					break;				  case 0:					ram_outb(ccard, &ReqOut->ReqId, reqbuf->ReqId); 					break;				  case 2:					if (!reqbuf->Reference) 						ep = &chan->de;					else						ep = &chan->be;					ep->Id = reqbuf->ReqId;					break;				}				tmpid = reqbuf->ReqId;				if (!reqbuf->Reference) 					chan->e.ReqCh = 0; 				 else					chan->e.ReqCh = 1; 			} 			switch(scom) {			  case 1:			 	chan->e.ref = ccard->ref_out++;				break;			  case 0:			 	chan->e.ref = ram_inw(ccard, &ReqOut->Reference);				break;			  case 2:				chan->e.ref = chan->No;				break;			}			chan->e.Req = reqbuf->Req;			ReqCount++; 			switch (scom) {			  case 1:				ram_outb(ccard, &com->Req, reqbuf->Req); 				break;			  case 0:				ram_outw(ccard, &prram->NextReq, ram_inw(ccard, &ReqOut->next)); 				break;			  case 2:#ifdef CONFIG_ISDN_DRV_EICON_PCI				if (!ep) break;				ep->callback = eicon_idi_callback;				ep->R = (BUFFERS *)ccard;				ep->user[0] = (word)chan->No;				ep->user[1] = (word)tmpid;				ep->XNum = 1;				ep->RNum = 0;				ep->RNR = 0;				ep->Rc = 0;				ep->Ind = 0;				ep->X->PLength = reqbuf->XBuffer.length;				memcpy(ep->X->P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);				ep->ReqCh = reqbuf->ReqCh;				ep->Req = reqbuf->Req;#endif				break;			}			chan->e.busy = 1;			spin_unlock_irqrestore(&eicon_lock, flags);	               	eicon_log(ccard, dlev, "eicon: Req=%d Id=%x Ch=%d Len=%d Ref=%d\n", 					reqbuf->Req, tmpid, 					reqbuf->ReqCh, reqbuf->XBuffer.length,					chan->e.ref); #ifdef CONFIG_ISDN_DRV_EICON_PCI			if (scom == 2) {				if (ep) {					ccard->d->request(ep);					if (ep->Rc)						eicon_idi_callback(ep);				}			}#endif		  }		  dev_kfree_skb(skb);		 }		 dev_kfree_skb(skb2);		} 		else {			skb_queue_tail(&ccard->sackq, skb2);        	       	eicon_log(ccard, 128, "eicon: transmit: busy chan %d\n", chan->No); 		}		switch(scom) {			case 1:				quloop = 0;				break;			case 0:			case 2:				if (!(skb2 = skb_dequeue(&ccard->sndq)))					quloop = 0;				break;		}	}	if (!scom)		ram_outb(ccard, &prram->ReqInput, (__u8)(ram_inb(ccard, &prram->ReqInput) + ReqCount)); 	while((skb = skb_dequeue(&ccard->sackq))) { 		skb_queue_tail(&ccard->sndq, skb);	}}#ifdef CONFIG_ISDN_DRV_EICON_ISA/* * IRQ handler  */voideicon_irq(int irq, void *dev_id, struct pt_regs *regs) {	eicon_card *ccard = (eicon_card *)dev_id;        eicon_isa_card *isa_card;	eicon_pr_ram  *prram = 0;	eicon_isa_com	*com = 0;        eicon_RC *RcIn;        eicon_IND *IndIn;	struct sk_buff *skb;        int Count = 0;	int Rc = 0;	int Ind = 0;	unsigned char *irqprobe = 0;	int scom = 0;	int tmp = 0;	int dlev = 0;        if (!ccard) {                eicon_log(ccard, 1, "eicon_irq: spurious interrupt %d\n", irq);                return;        }	if (ccard->type == EICON_CTYPE_QUADRO) {		tmp = 4;		while(tmp) {			com = (eicon_isa_com *)ccard->hwif.isa.shmem;			if ((readb(ccard->hwif.isa.intack))) { /* quadro found */				break;			}			ccard = ccard->qnext;			tmp--;		}	}	isa_card = &ccard->hwif.isa;	switch(ccard->type) {		case EICON_CTYPE_S:		case EICON_CTYPE_SX:		case EICON_CTYPE_SCOM:		case EICON_CTYPE_QUADRO:			scom = 1;			com = (eicon_isa_com *)isa_card->shmem;			irqprobe = &isa_card->irqprobe;			break;		case EICON_CTYPE_S2M:			scom = 0;			prram = (eicon_pr_ram *)isa_card->shmem;			irqprobe = &isa_card->irqprobe;			break;		default:                	eicon_log(ccard, 1, "eicon_irq: unsupported card-type!\n");			return;	}	if (*irqprobe) {		switch(ccard->type) {			case EICON_CTYPE_S:			case EICON_CTYPE_SX:			case EICON_CTYPE_SCOM:			case EICON_CTYPE_QUADRO:				if (readb(isa_card->intack)) {        		               	writeb(0, &com->Rc);					writeb(0, isa_card->intack);				}				(*irqprobe)++;				break;			case EICON_CTYPE_S2M:				if (readb(isa_card->intack)) {        		               	writeb(0, &prram->RcOutput);					writeb(0, isa_card->intack);				}				(*irqprobe)++;				break;		}		return;	}	switch(ccard->type) {		case EICON_CTYPE_S:		case EICON_CTYPE_SX:		case EICON_CTYPE_SCOM:		case EICON_CTYPE_QUADRO:		case EICON_CTYPE_S2M:			if (!(readb(isa_card->intack))) { /* card did not interrupt */				eicon_log(ccard, 1, "eicon: IRQ: card reports no interrupt!\n");				return;			} 			break;	}    if (scom) {        /* if a return code is available ...  */	if ((tmp = ram_inb(ccard, &com->Rc))) {		eicon_RC *ack;		if (tmp == READY_INT) {                       	eicon_log(ccard, 64, "eicon: IRQ Rc=READY_INT\n");			if (ccard->ReadyInt) {				ccard->ReadyInt--;				ram_outb(ccard, &com->Rc, 0);				eicon_schedule_tx(ccard);			}		} else {			skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);			if (!skb) {                		eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");			} else {				ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));				ack->Rc = tmp;				ack->RcId = ram_inb(ccard, &com->RcId);				ack->RcCh = ram_inb(ccard, &com->RcCh);				ack->Reference = ccard->ref_in++;               	        	eicon_log(ccard, 128, "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n",					tmp,ack->RcId,ack->RcCh,ack->Reference);				skb_queue_tail(&ccard->rackq, skb);				eicon_schedule_ack(ccard);			}			ram_outb(ccard, &com->Req, 0);			ram_outb(ccard, &com->Rc, 0);		}	} else {	        /* if an indication is available ...  */		if ((tmp = ram_inb(ccard, &com->Ind))) {			eicon_IND *ind;			int len = ram_inw(ccard, &com->RBuffer.length);			skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);			if (!skb) {                		eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");			} else {				ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));				ind->Ind = tmp;				ind->IndId = ram_inb(ccard, &com->IndId);				ind->IndCh = ram_inb(ccard, &com->IndCh);				ind->MInd  = ram_inb(ccard, &com->MInd);				ind->MLength = ram_inw(ccard, &com->MLength);				ind->RBuffer.length = len;				if ((tmp == 1) || (tmp == 8))					dlev = 128;				else					dlev = 192;                       		eicon_log(ccard, dlev, "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",					tmp,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len);				ram_copyfromcard(ccard, &ind->RBuffer.P, &com->RBuffer.P, len);				skb_queue_tail(&ccard->rcvq, skb);				eicon_schedule_rx(ccard);			}			ram_outb(ccard, &com->Ind, 0);		}	}    } else {        /* if return codes are available ...  */        if((Count = ram_inb(ccard, &prram->RcOutput))) {		eicon_RC *ack;                /* get the buffer address of the first return code */                RcIn = (eicon_RC *)&prram->B[ram_inw(ccard, &prram->NextRc)];                /* for all return codes do ...  */                while(Count--) {                        if((Rc=ram_inb(ccard, &RcIn->Rc))) {				skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);				if (!skb) {                			eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");				} else {					ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));					ack->Rc = Rc;					ack->RcId = ram_inb(ccard, &RcIn->RcId);					ack->RcCh = ram_inb(ccard, &RcIn->RcCh);					ack->Reference = ram_inw(ccard, &RcIn->Reference);        	                	eicon_log(ccard, 128, "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n",						Rc,ack->RcId,ack->RcCh,ack->Reference);					skb_queue_tail(&ccard->rackq, skb);					eicon_schedule_ack(ccard);				}                       		ram_outb(ccard, &RcIn->Rc, 0);                        }                        /* get buffer address of next return code   */                        RcIn = (eicon_RC *)&prram->B[ram_inw(ccard, &RcIn->next)];                }                /* clear all return codes (no chaining!) */                ram_outb(ccard, &prram->RcOutput, 0);        }        /* if indications are available ... */        if((Count = ram_inb(ccard, &prram->IndOutput))) {		eicon_IND *ind;                /* get the buffer address of the first indication */                IndIn = (eicon_IND *)&prram->B[ram_inw(ccard, &prram->NextInd)];                /* for all indications do ... */                while(Count--) {			Ind = ram_inb(ccard, &IndIn->Ind);			if(Ind) {				int len = ram_inw(ccard, &IndIn->RBuffer.length);				skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);				if (!skb) {                			eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");				} else {					ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));					ind->Ind = Ind;					ind->IndId = ram_inb(ccard, &IndIn->IndId);					ind->IndCh = ram_inb(ccard, &IndIn->IndCh);					ind->MInd  = ram_inb(ccard, &IndIn->MInd);					ind->MLength = ram_inw(ccard, &IndIn->MLength);					ind->RBuffer.length = len;					if ((Ind == 1) || (Ind == 8))						dlev = 128;					else						dlev = 192;                	        	eicon_log(ccard, dlev, "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",						Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len);	                                ram_copyfromcard(ccard, &ind->RBuffer.P, &IndIn->RBuffer.P, len);					skb_queue_tail(&ccard->rcvq, skb);					eicon_schedule_rx(ccard);				}				ram_outb(ccard, &IndIn->Ind, 0);                        }                        /* get buffer address of next indication  */                        IndIn = (eicon_IND *)&prram->B[ram_inw(ccard, &IndIn->next)];                }                ram_outb(ccard, &prram->IndOutput, 0);        }    } 	/* clear interrupt */	switch(ccard->type) {		case EICON_CTYPE_QUADRO:			writeb(0, isa_card->intack);			writeb(0, &com[0x401]);			break;		case EICON_CTYPE_S:		case EICON_CTYPE_SX:		case EICON_CTYPE_SCOM:		case EICON_CTYPE_S2M:			writeb(0, isa_card->intack);			break;	}  return;}#endif

⌨️ 快捷键说明

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