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

📄 c4.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 3 页
字号:
	return 0;}/* ------------------------------------------------------------- */static void c4_dispatch_tx(avmcard *card){	avmcard_dmainfo *dma = card->dma;	unsigned long flags;	struct sk_buff *skb;	__u8 cmd, subcmd;	__u16 len;	__u32 txlen;	void *p;		save_flags(flags);	cli();	if (card->csr & DBELL_DOWN_ARM) { /* tx busy */	        restore_flags(flags);		return;	}	skb = skb_dequeue(&dma->send_queue);	if (!skb) {#ifdef CONFIG_C4_DEBUG		printk(KERN_DEBUG "%s: tx underrun\n", card->name);#endif	        restore_flags(flags);		return;	}	len = CAPIMSG_LEN(skb->data);	if (len) {		cmd = CAPIMSG_COMMAND(skb->data);		subcmd = CAPIMSG_SUBCOMMAND(skb->data);		p = dma->sendbuf;		if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {			__u16 dlen = CAPIMSG_DATALEN(skb->data);			_put_byte(&p, SEND_DATA_B3_REQ);			_put_slice(&p, skb->data, len);			_put_slice(&p, skb->data + len, dlen);		} else {			_put_byte(&p, SEND_MESSAGE);			_put_slice(&p, skb->data, len);		}		txlen = (__u8 *)p - (__u8 *)dma->sendbuf;#ifdef CONFIG_C4_DEBUG		printk(KERN_DEBUG "%s: tx put msg len=%d\n", card->name, txlen);#endif	} else {		txlen = skb->len-2;#ifdef CONFIG_C4_POLLDEBUG		if (skb->data[2] == SEND_POLLACK)			printk(KERN_INFO "%s: ack to c4\n", card->name);#endif#ifdef CONFIG_C4_DEBUG		printk(KERN_DEBUG "%s: tx put 0x%x len=%d\n",				card->name, skb->data[2], txlen);#endif		memcpy(dma->sendbuf, skb->data+2, skb->len-2);	}	txlen = (txlen + 3) & ~3;	c4outmeml(card->mbase+MBOX_DOWN_ADDR, virt_to_phys(dma->sendbuf));	c4outmeml(card->mbase+MBOX_DOWN_LEN, txlen);	card->csr |= DBELL_DOWN_ARM;	c4outmeml(card->mbase+DOORBELL, DBELL_DOWN_ARM);	restore_flags(flags);	dev_kfree_skb_any(skb);}/* ------------------------------------------------------------- */static void queue_pollack(avmcard *card){	struct sk_buff *skb;	void *p;	skb = alloc_skb(3, GFP_ATOMIC);	if (!skb) {		printk(KERN_CRIT "%s: no memory, lost poll ack\n",					card->name);		return;	}	p = skb->data;	_put_byte(&p, 0);	_put_byte(&p, 0);	_put_byte(&p, SEND_POLLACK);	skb_put(skb, (__u8 *)p - (__u8 *)skb->data);	skb_queue_tail(&card->dma->send_queue, skb);	c4_dispatch_tx(card);}/* ------------------------------------------------------------- */static void c4_handle_rx(avmcard *card){	avmcard_dmainfo *dma = card->dma;	struct capi_ctr *ctrl;	avmctrl_info *cinfo;	struct sk_buff *skb;	void *p = dma->recvbuf;	__u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;	__u8 b1cmd =  _get_byte(&p);	__u32 cidx;#ifdef CONFIG_C4_DEBUG	printk(KERN_DEBUG "%s: rx 0x%x len=%lu\n", card->name,				b1cmd, (unsigned long)dma->recvlen);#endif		switch (b1cmd) {	case RECEIVE_DATA_B3_IND:		ApplId = (unsigned) _get_word(&p);		MsgLen = _get_slice(&p, card->msgbuf);		DataB3Len = _get_slice(&p, card->databuf);		cidx = CAPIMSG_CONTROLLER(card->msgbuf)-card->cardnr;		if (cidx > 3) cidx = 0;		ctrl = card->ctrlinfo[cidx].capi_ctrl;		if (MsgLen < 30) { /* not CAPI 64Bit */			memset(card->msgbuf+MsgLen, 0, 30-MsgLen);			MsgLen = 30;			CAPIMSG_SETLEN(card->msgbuf, 30);		}		if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) {			printk(KERN_ERR "%s: incoming packet dropped\n",					card->name);		} else {			memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);			memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);			ctrl->handle_capimsg(ctrl, ApplId, skb);		}		break;	case RECEIVE_MESSAGE:		ApplId = (unsigned) _get_word(&p);		MsgLen = _get_slice(&p, card->msgbuf);		cidx = CAPIMSG_CONTROLLER(card->msgbuf)-card->cardnr;		if (cidx > 3) cidx = 0;		ctrl = card->ctrlinfo[cidx].capi_ctrl;		if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {			printk(KERN_ERR "%s: incoming packet dropped\n",					card->name);		} else {			memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);			ctrl->handle_capimsg(ctrl, ApplId, skb);		}		break;	case RECEIVE_NEW_NCCI:		ApplId = _get_word(&p);		NCCI = _get_word(&p);		WindowSize = _get_word(&p);		cidx = (NCCI&0x7f) - card->cardnr;		if (cidx > 3) cidx = 0;		ctrl = card->ctrlinfo[cidx].capi_ctrl;		ctrl->new_ncci(ctrl, ApplId, NCCI, WindowSize);		break;	case RECEIVE_FREE_NCCI:		ApplId = _get_word(&p);		NCCI = _get_word(&p);		if (NCCI != 0xffffffff) {			cidx = (NCCI&0x7f) - card->cardnr;			if (cidx > 3) cidx = 0;			ctrl = card->ctrlinfo[cidx].capi_ctrl;			ctrl->free_ncci(ctrl, ApplId, NCCI);		} else {			for (cidx=0; cidx < 4; cidx++) {				ctrl = card->ctrlinfo[cidx].capi_ctrl;				ctrl->appl_released(ctrl, ApplId);			}		}		break;	case RECEIVE_START:#ifdef CONFIG_C4_POLLDEBUG		printk(KERN_INFO "%s: poll from c4\n", card->name);#endif		if (!suppress_pollack)			queue_pollack(card);		for (cidx=0; cidx < 4; cidx++) {			ctrl = card->ctrlinfo[cidx].capi_ctrl;			ctrl->resume_output(ctrl);		}		break;	case RECEIVE_STOP:		for (cidx=0; cidx < 4; cidx++) {			ctrl = card->ctrlinfo[cidx].capi_ctrl;			ctrl->suspend_output(ctrl);		}		break;	case RECEIVE_INIT:	        cidx = card->nlogcontr++;	        cinfo = &card->ctrlinfo[cidx];		ctrl = cinfo->capi_ctrl;		cinfo->versionlen = _get_slice(&p, cinfo->versionbuf);		b1_parse_version(cinfo);		printk(KERN_INFO "%s: %s-card (%s) now active\n",		       card->name,		       cinfo->version[VER_CARDTYPE],		       cinfo->version[VER_DRIVER]);		ctrl->ready(cinfo->capi_ctrl);		break;	case RECEIVE_TASK_READY:		ApplId = (unsigned) _get_word(&p);		MsgLen = _get_slice(&p, card->msgbuf);		card->msgbuf[MsgLen] = 0;		while (    MsgLen > 0		       && (   card->msgbuf[MsgLen-1] == '\n'			   || card->msgbuf[MsgLen-1] == '\r')) {			card->msgbuf[MsgLen-1] = 0;			MsgLen--;		}		printk(KERN_INFO "%s: task %d \"%s\" ready.\n",				card->name, ApplId, card->msgbuf);		break;	case RECEIVE_DEBUGMSG:		MsgLen = _get_slice(&p, card->msgbuf);		card->msgbuf[MsgLen] = 0;		while (    MsgLen > 0		       && (   card->msgbuf[MsgLen-1] == '\n'			   || card->msgbuf[MsgLen-1] == '\r')) {			card->msgbuf[MsgLen-1] = 0;			MsgLen--;		}		printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);		break;	default:		printk(KERN_ERR "%s: c4_interrupt: 0x%x ???\n",				card->name, b1cmd);		return;	}}/* ------------------------------------------------------------- */static void c4_handle_interrupt(avmcard *card){	__u32 status = c4inmeml(card->mbase+DOORBELL);	if (status & DBELL_RESET_HOST) {		int i;		c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x0c);		printk(KERN_ERR "%s: unexpected reset\n", card->name);                for (i=0; i < 4; i++) {			avmctrl_info *cinfo = &card->ctrlinfo[i];			memset(cinfo->version, 0, sizeof(cinfo->version));			if (cinfo->capi_ctrl)				cinfo->capi_ctrl->reseted(cinfo->capi_ctrl);		}		return;	}	status &= (DBELL_UP_HOST | DBELL_DOWN_HOST);	if (!status)		return;	c4outmeml(card->mbase+DOORBELL, status);	if ((status & DBELL_UP_HOST) != 0) {		card->dma->recvlen = c4inmeml(card->mbase+MBOX_UP_LEN);		c4outmeml(card->mbase+MBOX_UP_LEN, 0);		c4_handle_rx(card);		card->dma->recvlen = 0;		c4outmeml(card->mbase+MBOX_UP_LEN, sizeof(card->dma->recvbuf));		c4outmeml(card->mbase+DOORBELL, DBELL_UP_ARM);	}	if ((status & DBELL_DOWN_HOST) != 0) {		card->csr &= ~DBELL_DOWN_ARM;	        c4_dispatch_tx(card);	} else if (card->csr & DBELL_DOWN_HOST) {		if (c4inmeml(card->mbase+MBOX_DOWN_LEN) == 0) {		        card->csr &= ~DBELL_DOWN_ARM;			c4_dispatch_tx(card);		}	}}static void c4_interrupt(int interrupt, void *devptr, struct pt_regs *regs){	avmcard *card;	card = (avmcard *) devptr;	if (!card) {		printk(KERN_WARNING "%s: interrupt: wrong device\n", card->name);		return;	}	if (card->interrupt) {		printk(KERN_ERR "%s: reentering interrupt hander\n",				card->name);		return;	}	card->interrupt = 1;	c4_handle_interrupt(card);	card->interrupt = 0;}/* ------------------------------------------------------------- */static void c4_send_init(avmcard *card){	struct sk_buff *skb;	void *p;	skb = alloc_skb(15, GFP_ATOMIC);	if (!skb) {		printk(KERN_CRIT "%s: no memory, lost register appl.\n",					card->name);		return;	}	p = skb->data;	_put_byte(&p, 0);	_put_byte(&p, 0);	_put_byte(&p, SEND_INIT);	_put_word(&p, AVM_NAPPS);	_put_word(&p, AVM_NCCI_PER_CHANNEL*30);	_put_word(&p, card->cardnr - 1);	skb_put(skb, (__u8 *)p - (__u8 *)skb->data);	skb_queue_tail(&card->dma->send_queue, skb);	c4_dispatch_tx(card);}static int queue_sendconfigword(avmcard *card, __u32 val){	struct sk_buff *skb;	void *p;	skb = alloc_skb(3+4, GFP_ATOMIC);	if (!skb) {		printk(KERN_CRIT "%s: no memory, send config\n",					card->name);		return -ENOMEM;	}	p = skb->data;	_put_byte(&p, 0);	_put_byte(&p, 0);	_put_byte(&p, SEND_CONFIG);	_put_word(&p, val);	skb_put(skb, (__u8 *)p - (__u8 *)skb->data);	skb_queue_tail(&card->dma->send_queue, skb);	c4_dispatch_tx(card);	return 0;}static int queue_sendconfig(avmcard *card, char cval[4]){	struct sk_buff *skb;	void *p;	skb = alloc_skb(3+4, GFP_ATOMIC);	if (!skb) {		printk(KERN_CRIT "%s: no memory, send config\n",					card->name);		return -ENOMEM;	}	p = skb->data;	_put_byte(&p, 0);	_put_byte(&p, 0);	_put_byte(&p, SEND_CONFIG);	_put_byte(&p, cval[0]);	_put_byte(&p, cval[1]);	_put_byte(&p, cval[2]);	_put_byte(&p, cval[3]);	skb_put(skb, (__u8 *)p - (__u8 *)skb->data);	skb_queue_tail(&card->dma->send_queue, skb);	c4_dispatch_tx(card);	return 0;}static int c4_send_config(avmcard *card, capiloaddatapart * config){	__u8 val[4];	unsigned char *dp;	int left, retval;		if ((retval = queue_sendconfigword(card, 1)) != 0)		return retval;	if ((retval = queue_sendconfigword(card, config->len)) != 0)		return retval;	dp = config->data;	left = config->len;	while (left >= sizeof(__u32)) {	        if (config->user) {			retval = copy_from_user(val, dp, sizeof(val));			if (retval)				return -EFAULT;		} else {			memcpy(val, dp, sizeof(val));		}		if ((retval = queue_sendconfig(card, val)) != 0)			return retval;		left -= sizeof(val);		dp += sizeof(val);	}	if (left) {		memset(val, 0, sizeof(val));		if (config->user) {			retval = copy_from_user(&val, dp, left);			if (retval)				return -EFAULT;		} else {			memcpy(&val, dp, left);		}		if ((retval = queue_sendconfig(card, val)) != 0)			return retval;	}	return 0;}static int c4_load_firmware(struct capi_ctr *ctrl, capiloaddata *data){	avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);	avmcard *card = cinfo->card;	unsigned long flags;	int retval;	if ((retval = c4_load_t4file(card, &data->firmware))) {		printk(KERN_ERR "%s: failed to load t4file!!\n",					card->name);		c4_reset(card);		return retval;	}	save_flags(flags);	cli();	card->csr = 0;	c4outmeml(card->mbase+MBOX_UP_LEN, 0);	c4outmeml(card->mbase+MBOX_DOWN_LEN, 0);	c4outmeml(card->mbase+DOORBELL, DBELL_INIT);	mdelay(1);	c4outmeml(card->mbase+DOORBELL,			DBELL_UP_HOST | DBELL_DOWN_HOST | DBELL_RESET_HOST);	c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x08);	card->dma->recvlen = 0;	c4outmeml(card->mbase+MBOX_UP_ADDR, virt_to_phys(card->dma->recvbuf));	c4outmeml(card->mbase+MBOX_UP_LEN, sizeof(card->dma->recvbuf));	c4outmeml(card->mbase+DOORBELL, DBELL_UP_ARM);	restore_flags(flags);

⌨️ 快捷键说明

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