ioctl.c

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

C
602
字号
/* * 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;		kfree(rcvmsg);		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, SCIOC_SRECSIZE)) {			kfree(rcvmsg);			kfree(srec);			return -EFAULT;		}		status = send_and_receive(card, CMPID, cmReqType2, cmReqClass0, cmReqLoadProc,				0, SCIOC_SRECSIZE, 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(spid);			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;	}	

⌨️ 快捷键说明

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