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

📄 ioctl.c

📁 linux-2.6.15.6
💻 C
字号:
/* * Copyright (C) 1996  SpellCaster Telecommunications Inc. * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * */#include "includes.h"#include "hardware.h"#include "message.h"#include "card.h"#include "scioc.h"extern int indicate_status(int, int, unsigned long, char *);extern int startproc(int);extern int reset(int);extern int send_and_receive(int, unsigned int, unsigned char,unsigned char,		unsigned char,unsigned char, 		unsigned char, unsigned char *, RspMessage *, int);extern board *sc_adapter[];static int GetStatus(int card, boardInfo *);/* * Process private IOCTL messages (typically from scctrl) */int sc_ioctl(int card, scs_ioctl *data){	int		status;	RspMessage	*rcvmsg;	char		*spid;	char		*dn;	char		switchtype;	char		speed;	rcvmsg = kmalloc(sizeof(RspMessage), GFP_KERNEL);	if (!rcvmsg)		return -ENOMEM;	switch(data->command) {	case SCIOCRESET:	/* Perform a hard reset of the adapter */	{		pr_debug("%s: SCIOCRESET: ioctl received\n",			sc_adapter[card]->devicename);		sc_adapter[card]->StartOnReset = 0;		return (reset(card));	}	case SCIOCLOAD:	{		char *srec;		srec = kmalloc(SCIOC_SRECSIZE, GFP_KERNEL);		if (!srec) {			kfree(rcvmsg);			return -ENOMEM;		}		pr_debug("%s: SCIOLOAD: ioctl received\n",				sc_adapter[card]->devicename);		if(sc_adapter[card]->EngineUp) {			pr_debug("%s: SCIOCLOAD: command failed, LoadProc while engine running.\n",				sc_adapter[card]->devicename);			kfree(rcvmsg);			kfree(srec);			return -1;		}		/*		 * Get the SRec from user space		 */		if (copy_from_user(srec, data->dataptr, sizeof(srec))) {			kfree(rcvmsg);			kfree(srec);			return -EFAULT;		}		status = send_and_receive(card, CMPID, cmReqType2, cmReqClass0, cmReqLoadProc,				0, sizeof(srec), srec, rcvmsg, SAR_TIMEOUT);		kfree(rcvmsg);		kfree(srec);		if(status) {			pr_debug("%s: SCIOCLOAD: command failed, status = %d\n", 				sc_adapter[card]->devicename, status);			return -1;		}		else {			pr_debug("%s: SCIOCLOAD: command successful\n",					sc_adapter[card]->devicename);			return 0;		}	}	case SCIOCSTART:	{		pr_debug("%s: SCIOSTART: ioctl received\n",				sc_adapter[card]->devicename);		if(sc_adapter[card]->EngineUp) {			pr_debug("%s: SCIOCSTART: command failed, engine already running.\n",				sc_adapter[card]->devicename);			return -1;		}		sc_adapter[card]->StartOnReset = 1;		startproc(card);		return 0;	}	case SCIOCSETSWITCH:	{		pr_debug("%s: SCIOSETSWITCH: ioctl received\n",				sc_adapter[card]->devicename);		/*		 * Get the switch type from user space		 */		if (copy_from_user(&switchtype, data->dataptr, sizeof(char))) {			kfree(rcvmsg);			return -EFAULT;		}		pr_debug("%s: SCIOCSETSWITCH: setting switch type to %d\n",			sc_adapter[card]->devicename,			switchtype);		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallSetSwitchType,						0, sizeof(char),&switchtype, rcvmsg, SAR_TIMEOUT);		if(!status && !(rcvmsg->rsp_status)) {			pr_debug("%s: SCIOCSETSWITCH: command successful\n",				sc_adapter[card]->devicename);			kfree(rcvmsg);			return 0;		}		else {			pr_debug("%s: SCIOCSETSWITCH: command failed (status = %d)\n",				sc_adapter[card]->devicename, status);			kfree(rcvmsg);			return status;		}	}			case SCIOCGETSWITCH:	{		pr_debug("%s: SCIOGETSWITCH: ioctl received\n",				sc_adapter[card]->devicename);		/*		 * Get the switch type from the board		 */		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, 			ceReqCallGetSwitchType, 0, 0, NULL, rcvmsg, SAR_TIMEOUT);		if (!status && !(rcvmsg->rsp_status)) {			pr_debug("%s: SCIOCGETSWITCH: command successful\n",					sc_adapter[card]->devicename);		}		else {			pr_debug("%s: SCIOCGETSWITCH: command failed (status = %d)\n",				sc_adapter[card]->devicename, status);			kfree(rcvmsg);			return status;		}		switchtype = rcvmsg->msg_data.byte_array[0];		/*		 * Package the switch type and send to user space		 */		if (copy_to_user(data->dataptr, &switchtype,				 sizeof(char))) {			kfree(rcvmsg);			return -EFAULT;		}		kfree(rcvmsg);		return 0;	}	case SCIOCGETSPID:	{		pr_debug("%s: SCIOGETSPID: ioctl received\n",				sc_adapter[card]->devicename);		spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL);		if(!spid) {			kfree(rcvmsg);			return -ENOMEM;		}		/*		 * Get the spid from the board		 */		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetSPID,					data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT);		if (!status) {			pr_debug("%s: SCIOCGETSPID: command successful\n",					sc_adapter[card]->devicename);		}		else {			pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n",				sc_adapter[card]->devicename, status);			kfree(rcvmsg);			return status;		}		strcpy(spid, rcvmsg->msg_data.byte_array);		/*		 * Package the switch type and send to user space		 */		if (copy_to_user(data->dataptr, spid, SCIOC_SPIDSIZE)) {			kfree(spid);			kfree(rcvmsg);			return -EFAULT;		}		kfree(spid);		kfree(rcvmsg);		return 0;	}		case SCIOCSETSPID:	{		pr_debug("%s: DCBIOSETSPID: ioctl received\n",				sc_adapter[card]->devicename);		spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL);		if(!spid) {			kfree(rcvmsg);			return -ENOMEM;		}		/*		 * Get the spid from user space		 */		if (copy_from_user(spid, data->dataptr, SCIOC_SPIDSIZE)) {			kfree(rcvmsg);			return -EFAULT;		}		pr_debug("%s: SCIOCSETSPID: setting channel %d spid to %s\n", 			sc_adapter[card]->devicename, data->channel, spid);		status = send_and_receive(card, CEPID, ceReqTypeCall, 			ceReqClass0, ceReqCallSetSPID, data->channel, 			strlen(spid), spid, rcvmsg, SAR_TIMEOUT);		if(!status && !(rcvmsg->rsp_status)) {			pr_debug("%s: SCIOCSETSPID: command successful\n", 				sc_adapter[card]->devicename);			kfree(rcvmsg);			kfree(spid);			return 0;		}		else {			pr_debug("%s: SCIOCSETSPID: command failed (status = %d)\n",				sc_adapter[card]->devicename, status);			kfree(rcvmsg);			kfree(spid);			return status;		}	}	case SCIOCGETDN:	{		pr_debug("%s: SCIOGETDN: ioctl received\n",				sc_adapter[card]->devicename);		/*		 * Get the dn from the board		 */		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetMyNumber,					data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT);		if (!status) {			pr_debug("%s: SCIOCGETDN: command successful\n",					sc_adapter[card]->devicename);		}		else {			pr_debug("%s: SCIOCGETDN: command failed (status = %d)\n",				sc_adapter[card]->devicename, status);			kfree(rcvmsg);			return status;		}		dn = kmalloc(SCIOC_DNSIZE, GFP_KERNEL);		if (!dn) {			kfree(rcvmsg);			return -ENOMEM;		}		strcpy(dn, rcvmsg->msg_data.byte_array);		kfree(rcvmsg);		/*		 * Package the dn and send to user space		 */		if (copy_to_user(data->dataptr, dn, SCIOC_DNSIZE)) {			kfree(dn);			return -EFAULT;		}		kfree(dn);		return 0;	}		case SCIOCSETDN:	{		pr_debug("%s: SCIOSETDN: ioctl received\n",				sc_adapter[card]->devicename);		dn = kmalloc(SCIOC_DNSIZE, GFP_KERNEL);		if (!dn) {			kfree(rcvmsg);			return -ENOMEM;		}		/*		 * Get the spid from user space		 */		if (copy_from_user(dn, data->dataptr, SCIOC_DNSIZE)) {			kfree(rcvmsg);			kfree(dn);			return -EFAULT;		}		pr_debug("%s: SCIOCSETDN: setting channel %d dn to %s\n", 			sc_adapter[card]->devicename, data->channel, dn);		status = send_and_receive(card, CEPID, ceReqTypeCall, 			ceReqClass0, ceReqCallSetMyNumber, data->channel, 			strlen(dn),dn,rcvmsg, SAR_TIMEOUT);		if(!status && !(rcvmsg->rsp_status)) {			pr_debug("%s: SCIOCSETDN: command successful\n", 				sc_adapter[card]->devicename);			kfree(rcvmsg);			kfree(dn);			return 0;		}		else {			pr_debug("%s: SCIOCSETDN: command failed (status = %d)\n",				sc_adapter[card]->devicename, status);			kfree(rcvmsg);			kfree(dn);			return status;		}	}	case SCIOCTRACE:		pr_debug("%s: SCIOTRACE: ioctl received\n",				sc_adapter[card]->devicename);/*		sc_adapter[card]->trace = !sc_adapter[card]->trace;		pr_debug("%s: SCIOCTRACE: tracing turned %s\n",				sc_adapter[card]->devicename,			sc_adapter[card]->trace ? "ON" : "OFF"); */		break;	case SCIOCSTAT:	{		boardInfo *bi;		pr_debug("%s: SCIOSTAT: ioctl received\n",				sc_adapter[card]->devicename);		bi = kmalloc (sizeof(boardInfo), GFP_KERNEL);		if (!bi) {			kfree(rcvmsg);			return -ENOMEM;		}		kfree(rcvmsg);		GetStatus(card, bi);		if (copy_to_user(data->dataptr, bi, sizeof(boardInfo))) {			kfree(bi);			return -EFAULT;		}		kfree(bi);		return 0;	}	case SCIOCGETSPEED:	{		pr_debug("%s: SCIOGETSPEED: ioctl received\n",				sc_adapter[card]->devicename);		/*		 * Get the speed from the board		 */		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, 			ceReqCallGetCallType, data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT);		if (!status && !(rcvmsg->rsp_status)) {			pr_debug("%s: SCIOCGETSPEED: command successful\n",				sc_adapter[card]->devicename);		}		else {			pr_debug("%s: SCIOCGETSPEED: command failed (status = %d)\n",				sc_adapter[card]->devicename, status);			kfree(rcvmsg);			return status;		}		speed = rcvmsg->msg_data.byte_array[0];		kfree(rcvmsg);		/*		 * Package the switch type and send to user space		 */		if (copy_to_user(data->dataptr, &speed, sizeof(char)))			return -EFAULT;		return 0;	}	case SCIOCSETSPEED:		pr_debug("%s: SCIOCSETSPEED: ioctl received\n",				sc_adapter[card]->devicename);		break;	case SCIOCLOOPTST:		pr_debug("%s: SCIOCLOOPTST: ioctl received\n",				sc_adapter[card]->devicename);		break;	default:		kfree(rcvmsg);		return -1;	}	kfree(rcvmsg);	return 0;}static int GetStatus(int card, boardInfo *bi){	RspMessage rcvmsg;	int i, status;	/*	 * Fill in some of the basic info about the board	 */	bi->modelid = sc_adapter[card]->model;	strcpy(bi->serial_no, sc_adapter[card]->hwconfig.serial_no);	strcpy(bi->part_no, sc_adapter[card]->hwconfig.part_no);	bi->iobase = sc_adapter[card]->iobase;	bi->rambase = sc_adapter[card]->rambase;	bi->irq = sc_adapter[card]->interrupt;	bi->ramsize = sc_adapter[card]->hwconfig.ram_size;	bi->interface = sc_adapter[card]->hwconfig.st_u_sense;	strcpy(bi->load_ver, sc_adapter[card]->load_ver);	strcpy(bi->proc_ver, sc_adapter[card]->proc_ver);	/*	 * Get the current PhyStats and LnkStats	 */	status = send_and_receive(card, CEPID, ceReqTypePhy, ceReqClass2,		ceReqPhyStatus, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);	if(!status) {		if(sc_adapter[card]->model < PRI_BOARD) {			bi->l1_status = rcvmsg.msg_data.byte_array[2];			for(i = 0 ; i < BRI_CHANNELS ; i++)				bi->status.bristats[i].phy_stat =					rcvmsg.msg_data.byte_array[i];		}		else {			bi->l1_status = rcvmsg.msg_data.byte_array[0];			bi->l2_status = rcvmsg.msg_data.byte_array[1];			for(i = 0 ; i < PRI_CHANNELS ; i++)				bi->status.pristats[i].phy_stat = 					rcvmsg.msg_data.byte_array[i+2];		}	}		/*	 * Get the call types for each channel	 */	for (i = 0 ; i < sc_adapter[card]->nChannels ; i++) {		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0,			ceReqCallGetCallType, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);		if(!status) {			if (sc_adapter[card]->model == PRI_BOARD) {				bi->status.pristats[i].call_type = 					rcvmsg.msg_data.byte_array[0];			}			else {				bi->status.bristats[i].call_type =					rcvmsg.msg_data.byte_array[0];			}		}	}		/*	 * If PRI, get the call states and service states for each channel	 */	if (sc_adapter[card]->model == PRI_BOARD) {		/*		 * Get the call states		 */		status = send_and_receive(card, CEPID, ceReqTypeStat, ceReqClass2,			ceReqPhyChCallState, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);		if(!status) {			for( i = 0 ; i < PRI_CHANNELS ; i++ )				bi->status.pristats[i].call_state = 					rcvmsg.msg_data.byte_array[i];		}		/*		 * Get the service states		 */		status = send_and_receive(card, CEPID, ceReqTypeStat, ceReqClass2,			ceReqPhyChServState, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);		if(!status) {			for( i = 0 ; i < PRI_CHANNELS ; i++ )				bi->status.pristats[i].serv_state = 					rcvmsg.msg_data.byte_array[i];		}		/*		 * Get the link stats for the channels		 */		for (i = 1 ; i <= PRI_CHANNELS ; i++) {			status = send_and_receive(card, CEPID, ceReqTypeLnk, ceReqClass0,				ceReqLnkGetStats, i, 0, NULL, &rcvmsg, SAR_TIMEOUT);			if (!status) {				bi->status.pristats[i-1].link_stats.tx_good =					(unsigned long)rcvmsg.msg_data.byte_array[0];				bi->status.pristats[i-1].link_stats.tx_bad =					(unsigned long)rcvmsg.msg_data.byte_array[4];				bi->status.pristats[i-1].link_stats.rx_good =					(unsigned long)rcvmsg.msg_data.byte_array[8];				bi->status.pristats[i-1].link_stats.rx_bad =					(unsigned long)rcvmsg.msg_data.byte_array[12];			}		}		/*		 * Link stats for the D channel		 */		status = send_and_receive(card, CEPID, ceReqTypeLnk, ceReqClass0,			ceReqLnkGetStats, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);		if (!status) {			bi->dch_stats.tx_good = (unsigned long)rcvmsg.msg_data.byte_array[0];			bi->dch_stats.tx_bad = (unsigned long)rcvmsg.msg_data.byte_array[4];			bi->dch_stats.rx_good = (unsigned long)rcvmsg.msg_data.byte_array[8];			bi->dch_stats.rx_bad = (unsigned long)rcvmsg.msg_data.byte_array[12];		}		return 0;	}	/*	 * If BRI or POTS, Get SPID, DN and call types for each channel	 */	/*	 * Get the link stats for the channels	 */	status = send_and_receive(card, CEPID, ceReqTypeLnk, ceReqClass0,		ceReqLnkGetStats, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);	if (!status) {		bi->dch_stats.tx_good = (unsigned long)rcvmsg.msg_data.byte_array[0];		bi->dch_stats.tx_bad = (unsigned long)rcvmsg.msg_data.byte_array[4];		bi->dch_stats.rx_good = (unsigned long)rcvmsg.msg_data.byte_array[8];		bi->dch_stats.rx_bad = (unsigned long)rcvmsg.msg_data.byte_array[12];		bi->status.bristats[0].link_stats.tx_good = 			(unsigned long)rcvmsg.msg_data.byte_array[16];		bi->status.bristats[0].link_stats.tx_bad = 			(unsigned long)rcvmsg.msg_data.byte_array[20];		bi->status.bristats[0].link_stats.rx_good = 			(unsigned long)rcvmsg.msg_data.byte_array[24];		bi->status.bristats[0].link_stats.rx_bad = 			(unsigned long)rcvmsg.msg_data.byte_array[28];		bi->status.bristats[1].link_stats.tx_good = 			(unsigned long)rcvmsg.msg_data.byte_array[32];		bi->status.bristats[1].link_stats.tx_bad = 			(unsigned long)rcvmsg.msg_data.byte_array[36];		bi->status.bristats[1].link_stats.rx_good = 			(unsigned long)rcvmsg.msg_data.byte_array[40];		bi->status.bristats[1].link_stats.rx_bad = 			(unsigned long)rcvmsg.msg_data.byte_array[44];	}	/*	 * Get the SPIDs	 */	for (i = 0 ; i < BRI_CHANNELS ; i++) {		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0,			ceReqCallGetSPID, i+1, 0, NULL, &rcvmsg, SAR_TIMEOUT);		if (!status)			strcpy(bi->status.bristats[i].spid, rcvmsg.msg_data.byte_array);	}			/*	 * Get the DNs	 */	for (i = 0 ; i < BRI_CHANNELS ; i++) {		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0,			ceReqCallGetMyNumber, i+1, 0, NULL, &rcvmsg, SAR_TIMEOUT);		if (!status)			strcpy(bi->status.bristats[i].dn, rcvmsg.msg_data.byte_array);	}			return 0;}

⌨️ 快捷键说明

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