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

📄 c4.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
		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.dmabuf;#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.dmabuf, skb->data+2, skb->len-2);	}	txlen = (txlen + 3) & ~3;	c4outmeml(card->mbase+MBOX_DOWN_ADDR, dma->sendbuf.dmaaddr);	c4outmeml(card->mbase+MBOX_DOWN_LEN, txlen);	card->csr |= DBELL_DOWN_ARM;	c4outmeml(card->mbase+DOORBELL, DBELL_DOWN_ARM);	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.dmabuf;	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 >= card->nlogcontr) 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);			capi_ctr_handle_message(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 >= card->nlogcontr) cidx = 0;		cinfo = &card->ctrlinfo[cidx];		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);			if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)				capilib_data_b3_conf(&cinfo->ncci_head, ApplId,						     CAPIMSG_NCCI(skb->data),						     CAPIMSG_MSGID(skb->data));			capi_ctr_handle_message(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 >= card->nlogcontr) cidx = 0;		capilib_new_ncci(&card->ctrlinfo[cidx].ncci_head, 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 >= card->nlogcontr) cidx = 0;			capilib_free_ncci(&card->ctrlinfo[cidx].ncci_head, ApplId, NCCI);		}		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 < card->nr_controllers; cidx++) {			ctrl = &card->ctrlinfo[cidx].capi_ctrl;			capi_ctr_resume_output(ctrl);		}		break;	case RECEIVE_STOP:		for (cidx=0; cidx < card->nr_controllers; cidx++) {			ctrl = &card->ctrlinfo[cidx].capi_ctrl;			capi_ctr_suspend_output(ctrl);		}		break;	case RECEIVE_INIT:	        cidx = card->nlogcontr;		if (cidx >= card->nr_controllers) {			printk(KERN_ERR "%s: card with %d controllers ??\n",					card->name, cidx+1);			break;		}	        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]);		capi_ctr_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 irqreturn_t c4_handle_interrupt(avmcard *card){	unsigned long flags;	u32 status;	spin_lock_irqsave(&card->lock, flags);	status = c4inmeml(card->mbase+DOORBELL);	if (status & DBELL_RESET_HOST) {		u_int i;		c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x0c);		spin_unlock_irqrestore(&card->lock, flags);		if (card->nlogcontr == 0)			return IRQ_HANDLED;		printk(KERN_ERR "%s: unexpected reset\n", card->name);                for (i=0; i < card->nr_controllers; i++) {			avmctrl_info *cinfo = &card->ctrlinfo[i];			memset(cinfo->version, 0, sizeof(cinfo->version));			capilib_release(&cinfo->ncci_head);			capi_ctr_reseted(&cinfo->capi_ctrl);		}		card->nlogcontr = 0;		return IRQ_HANDLED;	}	status &= (DBELL_UP_HOST | DBELL_DOWN_HOST);	if (!status) {		spin_unlock_irqrestore(&card->lock, flags);		return IRQ_HANDLED;	}	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, card->dma->recvbuf.size);		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);		}	}	spin_unlock_irqrestore(&card->lock, flags);	return IRQ_HANDLED;}static irqreturn_t c4_interrupt(int interrupt, void *devptr, struct pt_regs *regs){	avmcard *card = devptr;	return c4_handle_interrupt(card);}/* ------------------------------------------------------------- */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, CAPI_MAXAPPL);	_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;	unsigned long flags;	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);		spin_lock_irqsave(&card->lock, flags);	c4_dispatch_tx(card);	spin_unlock_irqrestore(&card->lock, flags);	return 0;}static int c4_send_config(avmcard *card, capiloaddatapart * config){	u8 val[4];	unsigned char *dp;	u_int left;	int 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) {			if (copy_from_user(val, dp, sizeof(val)))				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) {			if (copy_from_user(&val, dp, left))				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;	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;	}	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, card->dma->recvbuf.dmaaddr);	c4outmeml(card->mbase+MBOX_UP_LEN, card->dma->recvbuf.size);	c4outmeml(card->mbase+DOORBELL, DBELL_UP_ARM);	if (data->configuration.len > 0 && data->configuration.data) {		retval = c4_send_config(card, &data->configuration);		if (retval) {

⌨️ 快捷键说明

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