ioctl.c

来自「LINUX 2.6.17.4的源码」· C语言 代码 · 共 602 行 · 第 1/2 页

C
602
字号
	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 + =
减小字号Ctrl + -
显示快捷键?