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

📄 tpam_commands.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
		return -ENOMEM;	tpam_enqueue(card, skb);	return 0;}/* * Send data through the board. This function encodes the data depending * on the connection type (modem or HDLC), then builds and sends a U3DataReq. * * 	driverId: the driver id (really meaning here the board) * 	channel: the channel number * 	ack: data needs to be acknowledged upon send * 	skb: sk_buff containing the data * * Return: size of data send if OK, <0 if error. */int tpam_writebuf_skb(int driverId, int channel, int ack, struct sk_buff *skb) {	tpam_card *card;	int orig_size = skb->len;	void *finaldata;	u32 finallen;	dprintk("TurboPAM(tpam_writebuf_skb): "		"card=%d, channel=%ld, ack=%d, data size=%d\n", 		driverId, (unsigned long)channel, ack, skb->len);	/* find the board based on its driver ID */	if (!(card = tpam_findcard(driverId))) {		printk(KERN_ERR "TurboPAM(tpam_writebuf_skb): "		       "invalid driverId %d\n", driverId);			return -ENODEV;	}	/* board must be running */	if (!card->running)		return -ENODEV;	/* allocate some temporary memory */	if (!(finaldata = (void *)__get_free_page(GFP_ATOMIC))) {		printk(KERN_ERR "TurboPAM(tpam_writebuf_skb): "		       "get_free_page failed\n");		return -ENOMEM;	}	/* encode the data */	if (!card->channels[channel].realhdlc) {		/* modem mode */		hdlc_encode_modem(skb->data, skb->len, finaldata, &finallen);	}	else {		/* HDLC mode */		void *tempdata;		u32 templen;		if (!(tempdata = (void *)__get_free_page(GFP_ATOMIC))) {			printk(KERN_ERR "TurboPAM(tpam_writebuf_skb): "			       "get_free_page failed\n");			free_page((u32)finaldata);			return -ENOMEM;		}		hdlc_no_accm_encode(skb->data, skb->len, tempdata, &templen);		finallen = tpam_hdlc_encode(tempdata, finaldata, 				       &card->channels[channel].hdlcshift, 				       templen);		free_page((u32)tempdata);	}	/* free the old sk_buff */	kfree_skb(skb);	/* build and send a U3DataReq */	skb = build_U3DataReq(card->channels[channel].ncoid, finaldata, 			      finallen, ack, orig_size);	if (!skb) {		free_page((u32)finaldata);		return -ENOMEM;	}	tpam_enqueue_data(&card->channels[channel], skb);	/* free the temporary memory */	free_page((u32)finaldata);	return orig_size;}/* * Treat a received ACreateNCOCnf message. * * 	card: the board * 	skb: the received message */void tpam_recv_ACreateNCOCnf(tpam_card *card, struct sk_buff *skb) {	u32 ncoid;	u8 status;	u32 channel;	dprintk("TurboPAM(tpam_recv_ACreateNCOCnf): card=%d\n", card->id);	/* parse the message contents */	if (parse_ACreateNCOCnf(skb, &status, &ncoid))		return;	/* if the card is alreay running, it means that this message	 * arrives too late... */	if (card->running) {		printk(KERN_ERR "TurboPAM(tpam_recv_ACreateNCOCnf): "		       "ACreateNCOCnf received too late, status=%d\n", status);		return;	}	/* the NCO creation failed, the corresponding channel will	 * be unused */	if (status) {		printk(KERN_ERR "TurboPAM(tpam_recv_ACreateNCOCnf): "		       "ACreateNCO failed, status=%d\n", status);		card->channels_tested++;		return;	}	/* find the first free channel and assign the nco ID to it */	if ((channel = tpam_findchannel(card, TPAM_NCOID_INVALID)) == TPAM_CHANNEL_INVALID) {		printk(KERN_ERR "TurboPAM(tpam_recv_ACreateNCOCnf): "		       "All channels are assigned\n");		return;	}	card->channels[channel].ncoid = ncoid;	card->channels_tested++;	card->channels_used++;}/* * Treat a received ADestroyNCOCnf message. Not used by the driver. * * 	card: the board * 	skb: the received message */void tpam_recv_ADestroyNCOCnf(tpam_card *card, struct sk_buff *skb) {	u32 ncoid;	u8 status;	u32 channel;	dprintk("TurboPAM(tpam_recv_ADestroyNCOCnf): card=%d\n", card->id);	/* parse the message contents */	if (parse_ADestroyNCOCnf(skb, &status, &ncoid))		return;		if (status) {		printk(KERN_ERR "TurboPAM(tpam_recv_ADestroyNCOCnf): "		       "ADestroyNCO failed, status=%d\n", status);		return;	}	/* clears the channel's nco ID */	if ((channel = tpam_findchannel(card, ncoid)) == TPAM_CHANNEL_INVALID) {		printk(KERN_ERR "TurboPAM(tpam_recv_ADestroyNCOCnf): "		       "ncoid invalid %lu\n", (unsigned long)ncoid);		return;	}	card->channels[channel].ncoid = TPAM_NCOID_INVALID;}/* * Treat a received CConnectCnf message. * * 	card: the board * 	skb: the received message */void tpam_recv_CConnectCnf(tpam_card *card, struct sk_buff *skb) {	u32 ncoid;	u32 channel;	isdn_ctrl ctrl;	dprintk("TurboPAM(tpam_recv_CConnectCnf): card=%d\n", card->id);	/* parse the message contents */	if (parse_CConnectCnf(skb, &ncoid))		return;	/* find the channel by its nco ID */	if ((channel = tpam_findchannel(card, ncoid)) == TPAM_CHANNEL_INVALID) {		printk(KERN_ERR "TurboPAM(tpam_recv_CConnectCnf): "		       "ncoid invalid %lu\n", (unsigned long)ncoid);		return;	}	/* issue a DCONN command to the ISDN link layer if we are in HDLC mode.	 * In modem mode, we alreay did it - the ISDN timer kludge */	if (card->channels[channel].realhdlc) {		ctrl.driver = card->id;		ctrl.command = ISDN_STAT_DCONN;		ctrl.arg = channel;		(* card->interface.statcallb)(&ctrl);	}}/* * Treat a received CConnectInd message. This function signals a ICALL * to the ISDN link layer. * * 	card: the board * 	skb: the received message */void tpam_recv_CConnectInd(tpam_card *card, struct sk_buff *skb) {	u32 ncoid;	u32 channel;	u8 hdlc, plan, screen;	u8 calling[PHONE_MAXIMUMSIZE], called[PHONE_MAXIMUMSIZE];	isdn_ctrl ctrl;	int status;	dprintk("TurboPAM(tpam_recv_CConnectInd): card=%d\n", card->id);	/* parse the message contents */	if (parse_CConnectInd(skb, &ncoid, &hdlc, calling, called, &plan, &screen))		return;	/* find the channel by its nco ID */	if ((channel = tpam_findchannel(card, ncoid)) == TPAM_CHANNEL_INVALID) {		printk(KERN_ERR "TurboPAM(tpam_recv_CConnectInd): "		       "ncoid invalid %lu\n", (unsigned long)ncoid);		return;	}	/* initialize the channel parameters */	card->channels[channel].realhdlc = hdlc;	card->channels[channel].hdlcshift = 0;	card->channels[channel].readytoreceive = 0;	/* issue a ICALL command to the ISDN link layer */	ctrl.driver = card->id;	ctrl.command = ISDN_STAT_ICALL;	ctrl.arg = channel;	memcpy(ctrl.parm.setup.phone, calling, 32);	memcpy(ctrl.parm.setup.eazmsn, called, 32);	ctrl.parm.setup.si1 = 7;	/* data capability */	ctrl.parm.setup.si2 = 0;	ctrl.parm.setup.plan = plan;	ctrl.parm.setup.screen = screen;	status = (* card->interface.statcallb)(&ctrl);	switch (status) {		case 1:		case 4:			/* call accepted, link layer will send us a ACCEPTD 			 * command later */			dprintk("TurboPAM(tpam_recv_CConnectInd): "				"card=%d, channel=%d, icall waiting, status=%d\n", 				card->id, channel, status);			break;		default:			/* call denied, we build and send a CDisconnectReq */			dprintk("TurboPAM(tpam_recv_CConnectInd): "				"card=%d, channel=%d, icall denied, status=%d\n", 				card->id, channel, status);			skb = build_CDisconnectReq(ncoid);			if (!skb)				return;			tpam_enqueue(card, skb);	}}/* * Treat a received CDisconnectInd message. This function signals a DHUP and * a BHUP to the ISDN link layer. * * 	card: the board * 	skb: the received message */void tpam_recv_CDisconnectInd(tpam_card *card, struct sk_buff *skb) {	u32 ncoid;	u32 channel;	u32 cause;	isdn_ctrl ctrl;	dprintk("TurboPAM(tpam_recv_CDisconnectInd): card=%d\n", card->id);	/* parse the message contents */	if (parse_CDisconnectInd(skb, &ncoid, &cause))		return;	/* find the channel by its nco ID */	if ((channel = tpam_findchannel(card, ncoid)) == TPAM_CHANNEL_INVALID) {		printk(KERN_ERR "TurboPAM(tpam_recv_CDisconnectInd): "		       "ncoid invalid %lu\n", (unsigned long)ncoid);		return;	}	/* build and send a CDisconnectRsp */	skb = build_CDisconnectRsp(ncoid);	if (!skb)		return;	tpam_enqueue(card, skb);	/* issue a DHUP to the ISDN link layer */	ctrl.driver = card->id;	ctrl.command = ISDN_STAT_DHUP;	ctrl.arg = channel;	(* card->interface.statcallb)(&ctrl);	/* issue a BHUP to the ISDN link layer */	ctrl.driver = card->id;	ctrl.command = ISDN_STAT_BHUP;	ctrl.arg = channel;	(* card->interface.statcallb)(&ctrl);}/* * Treat a received CDisconnectCnf message. This function signals a DHUP and * a BHUP to the ISDN link layer. * * 	card: the board * 	skb: the received message */void tpam_recv_CDisconnectCnf(tpam_card *card, struct sk_buff *skb) {	u32 ncoid;	u32 channel;	u32 cause;	isdn_ctrl ctrl;	dprintk("TurboPAM(tpam_recv_CDisconnectCnf): card=%d\n", card->id);	/* parse the message contents */	if (parse_CDisconnectCnf(skb, &ncoid, &cause))		return;	/* find the channel by its nco ID */	if ((channel = tpam_findchannel(card, ncoid)) == TPAM_CHANNEL_INVALID) {		printk(KERN_ERR "TurboPAM(tpam_recv_CDisconnectCnf): "		       "ncoid invalid %lu\n", (unsigned long)ncoid);		return;	}	/* issue a DHUP to the ISDN link layer */	ctrl.driver = card->id;	ctrl.command = ISDN_STAT_DHUP;	ctrl.arg = channel;	(* card->interface.statcallb)(&ctrl);	/* issue a BHUP to the ISDN link layer */	ctrl.driver = card->id;	ctrl.command = ISDN_STAT_BHUP;	ctrl.arg = channel;	(* card->interface.statcallb)(&ctrl);}/* * Treat a received U3DataInd message. This function decodes the data * depending on the connection type (modem or HDLC) and passes it to the * ISDN link layer by using rcvcallb_skb. * * 	card: the board * 	skb: the received message + data */void tpam_recv_U3DataInd(tpam_card *card, struct sk_buff *skb) {	u32 ncoid;	u32 channel;	u8 *data;	u16 len;	struct sk_buff *result;	dprintk("TurboPAM(tpam_recv_U3DataInd): card=%d, datalen=%d\n", 		card->id, skb->len);	/* parse the message contents */	if (parse_U3DataInd(skb, &ncoid, &data, &len))		return;	/* find the channel by its nco ID */	if ((channel = tpam_findchannel(card, ncoid)) == TPAM_CHANNEL_INVALID) {		printk(KERN_ERR "TurboPAM(tpam_recv_U3DataInd): "		       "ncoid invalid %lu\n", (unsigned long)ncoid);		return;	}	/* decode the data */	if (card->channels[ncoid].realhdlc) {		/* HDLC mode */		u8 *tempdata;		u32 templen;		if (!(tempdata = (void *)__get_free_page(GFP_ATOMIC))) {			printk(KERN_ERR "TurboPAM(tpam_recv_U3DataInd): "			       "get_free_page failed\n");			return;		}		templen = tpam_hdlc_decode(data, tempdata, len);		templen = hdlc_no_accm_decode(tempdata, templen);		if (!(result = alloc_skb(templen, GFP_ATOMIC))) {			printk(KERN_ERR "TurboPAM(tpam_recv_U3DataInd): "			       "alloc_skb failed\n");			free_page((u32)tempdata);			return;		}		memcpy(skb_put(result, templen), tempdata, templen);		free_page((u32)tempdata);	}	else {		/* modem mode */		if (!(result = alloc_skb(len, GFP_ATOMIC))) {			printk(KERN_ERR "TurboPAM(tpam_recv_U3DataInd): "			       "alloc_skb failed\n");			return;		}		memcpy(skb_put(result, len), data, len);	}	/* In loop mode, resend the data immediatly */	if (card->loopmode) {		struct sk_buff *loopskb;		if (!(loopskb = alloc_skb(skb->len, GFP_ATOMIC))) {			printk(KERN_ERR "TurboPAM(tpam_recv_U3DataInd): "			       "alloc_skb failed\n");			kfree_skb(result);			return;		}		memcpy(skb_put(loopskb, result->len), result->data, 		       result->len);		if (tpam_writebuf_skb(card->id, channel, 0, loopskb) < 0)			kfree_skb(loopskb);	}	/* pass the data to the ISDN link layer */	(* card->interface.rcvcallb_skb)(card->id, channel, result);}/* * Treat a received U3ReadyToReceiveInd message. This function sets the * channel ready flag and triggers the send of data if the channel becomed * ready. * * 	card: the board * 	skb: the received message + data */void tpam_recv_U3ReadyToReceiveInd(tpam_card *card, struct sk_buff *skb) {	u32 ncoid;	u32 channel;	u8 ready;	dprintk("TurboPAM(tpam_recv_U3ReadyToReceiveInd): card=%d\n", card->id);	/* parse the message contents */	if (parse_U3ReadyToReceiveInd(skb, &ncoid, &ready))		return;	/* find the channel by its nco ID */	if ((channel = tpam_findchannel(card, ncoid)) == TPAM_CHANNEL_INVALID) {		printk(KERN_ERR "TurboPAM(tpam_recv_U3ReadyToReceiveInd): "		       "ncoid invalid %lu\n", (unsigned long)ncoid);		return;	}	/* set the readytoreceive flag */	card->channels[channel].readytoreceive = ready;	/* if the channel just becomed ready, trigger the send of queued data */	if (ready)		tpam_enqueue_data(&card->channels[channel], NULL);}/* * Runs the delayed statcallb when its timer expires. * * 	parm: pointer to the tpam_statcallb_data statcallb argument. */static void tpam_statcallb_run(unsigned long parm) {	tpam_statcallb_data *ds = (tpam_statcallb_data *)parm;	dprintk("TurboPAM(tpam_statcallb_run)\n");	(* ds->card->interface.statcallb)(&ds->ctrl);	kfree(ds->timer);	kfree(ds);}/* * Queues a statcallb call for delayed invocation. * * 	card: the board * 	ctrl: the statcallb argument */static void tpam_statcallb(tpam_card *card, isdn_ctrl ctrl) {	struct timer_list *timer;	tpam_statcallb_data *ds;	dprintk("TurboPAM(tpam_statcallb): card=%d\n", card->id);	if (!(timer = (struct timer_list *) kmalloc(sizeof(struct timer_list), 						    GFP_ATOMIC))) {		printk(KERN_ERR "TurboPAM: tpam_statcallb: kmalloc failed!\n");		return;	}	if (!(ds = (tpam_statcallb_data *) kmalloc(sizeof(tpam_statcallb_data),						   GFP_ATOMIC))) {		printk(KERN_ERR "TurboPAM: tpam_statcallb: kmalloc failed!\n");		kfree(timer);		return;	}	ds->card = card;	ds->timer = timer;	memcpy(&ds->ctrl, &ctrl, sizeof(isdn_ctrl));	init_timer(timer);	timer->function = tpam_statcallb_run;	timer->data = (unsigned long)ds;	timer->expires = jiffies + HZ / 10;   /* 0.1 second */	add_timer(timer);}

⌨️ 快捷键说明

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