rioctrl.c

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

C
1,498
字号
				else if (p->RIOBindTab[Entry] == (long)arg) {					/*					 ** Already exists - delete					 */					p->RIOBindTab[Entry] = 0L;					rio_dprintk(RIO_DEBUG_CTRL, "Removing Rta %ld from p->RIOBindTab\n", (unsigned long)arg);					return 0;				}			}			/*			 ** Dosen't exist - add			 */			if (EmptySlot != -1) {				p->RIOBindTab[EmptySlot] = (unsigned long)arg;				rio_dprintk(RIO_DEBUG_CTRL, "Adding Rta %lx to p->RIOBindTab\n", (unsigned long) arg);			} else {				rio_dprintk(RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %lx not added\n", (unsigned long) arg);				return -ENOMEM;			}			return 0;		}	case RIO_RESUME:		rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME\n");		port = (unsigned long) arg;		if ((port < 0) || (port > 511)) {			rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port);			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;			return -EINVAL;		}		PortP = p->RIOPortp[port];		if (!PortP->Mapped) {			rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not mapped\n", port);			p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;			return -EINVAL;		}		if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) {			rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not open\n", port);			return -EINVAL;		}		rio_spin_lock_irqsave(&PortP->portSem, flags);		if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RESUME) == RIO_FAIL) {			rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME failed\n");			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			return -EBUSY;		} else {			rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d resumed\n", port);			PortP->State |= RIO_BUSY;		}		rio_spin_unlock_irqrestore(&PortP->portSem, flags);		return retval;	case RIO_ASSIGN_RTA:		rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA\n");		if (!su) {			rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA !Root\n");			p->RIOError.Error = NOT_SUPER_USER;			return -EPERM;		}		if (copy_from_user(&MapEnt, arg, sizeof(MapEnt))) {			rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n");			p->RIOError.Error = COPYIN_FAILED;			return -EFAULT;		}		return RIOAssignRta(p, &MapEnt);	case RIO_CHANGE_NAME:		rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME\n");		if (!su) {			rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME !Root\n");			p->RIOError.Error = NOT_SUPER_USER;			return -EPERM;		}		if (copy_from_user(&MapEnt, arg, sizeof(MapEnt))) {			rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n");			p->RIOError.Error = COPYIN_FAILED;			return -EFAULT;		}		return RIOChangeName(p, &MapEnt);	case RIO_DELETE_RTA:		rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA\n");		if (!su) {			rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA !Root\n");			p->RIOError.Error = NOT_SUPER_USER;			return -EPERM;		}		if (copy_from_user(&MapEnt, arg, sizeof(MapEnt))) {			rio_dprintk(RIO_DEBUG_CTRL, "Copy from data space failed\n");			p->RIOError.Error = COPYIN_FAILED;			return -EFAULT;		}		return RIODeleteRta(p, &MapEnt);	case RIO_QUICK_CHECK:		if (copy_to_user(arg, &p->RIORtaDisCons, sizeof(unsigned int))) {			p->RIOError.Error = COPYOUT_FAILED;			return -EFAULT;		}		return 0;	case RIO_LAST_ERROR:		if (copy_to_user(arg, &p->RIOError, sizeof(struct Error)))			return -EFAULT;		return 0;	case RIO_GET_LOG:		rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_LOG\n");		return -EINVAL;	case RIO_GET_MODTYPE:		if (copy_from_user(&port, arg, sizeof(unsigned int))) {			p->RIOError.Error = COPYIN_FAILED;			return -EFAULT;		}		rio_dprintk(RIO_DEBUG_CTRL, "Get module type for port %d\n", port);		if (port < 0 || port > 511) {			rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Bad port number %d\n", port);			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;			return -EINVAL;		}		PortP = (p->RIOPortp[port]);		if (!PortP->Mapped) {			rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Port %d not mapped\n", port);			p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;			return -EINVAL;		}		/*		 ** Return module type of port		 */		port = PortP->HostP->UnixRups[PortP->RupNum].ModTypes;		if (copy_to_user(arg, &port, sizeof(unsigned int))) {			p->RIOError.Error = COPYOUT_FAILED;			return -EFAULT;		}		return (0);	case RIO_BLOCK_OPENS:		rio_dprintk(RIO_DEBUG_CTRL, "Opens block until booted\n");		for (Entry = 0; Entry < RIO_PORTS; Entry++) {			rio_spin_lock_irqsave(&PortP->portSem, flags);			p->RIOPortp[Entry]->WaitUntilBooted = 1;			rio_spin_unlock_irqrestore(&PortP->portSem, flags);		}		return 0;	case RIO_SETUP_PORTS:		rio_dprintk(RIO_DEBUG_CTRL, "Setup ports\n");		if (copy_from_user(&PortSetup, arg, sizeof(PortSetup))) {			p->RIOError.Error = COPYIN_FAILED;			rio_dprintk(RIO_DEBUG_CTRL, "EFAULT");			return -EFAULT;		}		if (PortSetup.From > PortSetup.To || PortSetup.To >= RIO_PORTS) {			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;			rio_dprintk(RIO_DEBUG_CTRL, "ENXIO");			return -ENXIO;		}		if (PortSetup.XpCps > p->RIOConf.MaxXpCps || PortSetup.XpCps < p->RIOConf.MinXpCps) {			p->RIOError.Error = XPRINT_CPS_OUT_OF_RANGE;			rio_dprintk(RIO_DEBUG_CTRL, "EINVAL");			return -EINVAL;		}		if (!p->RIOPortp) {			printk(KERN_ERR "rio: No p->RIOPortp array!\n");			rio_dprintk(RIO_DEBUG_CTRL, "No p->RIOPortp array!\n");			return -EIO;		}		rio_dprintk(RIO_DEBUG_CTRL, "entering loop (%d %d)!\n", PortSetup.From, PortSetup.To);		for (loop = PortSetup.From; loop <= PortSetup.To; loop++) {			rio_dprintk(RIO_DEBUG_CTRL, "in loop (%d)!\n", loop);		}		rio_dprintk(RIO_DEBUG_CTRL, "after loop (%d)!\n", loop);		rio_dprintk(RIO_DEBUG_CTRL, "Retval:%x\n", retval);		return retval;	case RIO_GET_PORT_SETUP:		rio_dprintk(RIO_DEBUG_CTRL, "Get port setup\n");		if (copy_from_user(&PortSetup, arg, sizeof(PortSetup))) {			p->RIOError.Error = COPYIN_FAILED;			return -EFAULT;		}		if (PortSetup.From >= RIO_PORTS) {			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;			return -ENXIO;		}		port = PortSetup.To = PortSetup.From;		PortSetup.IxAny = (p->RIOPortp[port]->Config & RIO_IXANY) ? 1 : 0;		PortSetup.IxOn = (p->RIOPortp[port]->Config & RIO_IXON) ? 1 : 0;		PortSetup.Drain = (p->RIOPortp[port]->Config & RIO_WAITDRAIN) ? 1 : 0;		PortSetup.Store = p->RIOPortp[port]->Store;		PortSetup.Lock = p->RIOPortp[port]->Lock;		PortSetup.XpCps = p->RIOPortp[port]->Xprint.XpCps;		memcpy(PortSetup.XpOn, p->RIOPortp[port]->Xprint.XpOn, MAX_XP_CTRL_LEN);		memcpy(PortSetup.XpOff, p->RIOPortp[port]->Xprint.XpOff, MAX_XP_CTRL_LEN);		PortSetup.XpOn[MAX_XP_CTRL_LEN - 1] = '\0';		PortSetup.XpOff[MAX_XP_CTRL_LEN - 1] = '\0';		if (copy_to_user(arg, &PortSetup, sizeof(PortSetup))) {			p->RIOError.Error = COPYOUT_FAILED;			return -EFAULT;		}		return retval;	case RIO_GET_PORT_PARAMS:		rio_dprintk(RIO_DEBUG_CTRL, "Get port params\n");		if (copy_from_user(&PortParams, arg, sizeof(struct PortParams))) {			p->RIOError.Error = COPYIN_FAILED;			return -EFAULT;		}		if (PortParams.Port >= RIO_PORTS) {			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;			return -ENXIO;		}		PortP = (p->RIOPortp[PortParams.Port]);		PortParams.Config = PortP->Config;		PortParams.State = PortP->State;		rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port);		if (copy_to_user(arg, &PortParams, sizeof(struct PortParams))) {			p->RIOError.Error = COPYOUT_FAILED;			return -EFAULT;		}		return retval;	case RIO_GET_PORT_TTY:		rio_dprintk(RIO_DEBUG_CTRL, "Get port tty\n");		if (copy_from_user(&PortTty, arg, sizeof(struct PortTty))) {			p->RIOError.Error = COPYIN_FAILED;			return -EFAULT;		}		if (PortTty.port >= RIO_PORTS) {			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;			return -ENXIO;		}		rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortTty.port);		PortP = (p->RIOPortp[PortTty.port]);		if (copy_to_user(arg, &PortTty, sizeof(struct PortTty))) {			p->RIOError.Error = COPYOUT_FAILED;			return -EFAULT;		}		return retval;	case RIO_SET_PORT_TTY:		if (copy_from_user(&PortTty, arg, sizeof(struct PortTty))) {			p->RIOError.Error = COPYIN_FAILED;			return -EFAULT;		}		rio_dprintk(RIO_DEBUG_CTRL, "Set port %d tty\n", PortTty.port);		if (PortTty.port >= (ushort) RIO_PORTS) {			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;			return -ENXIO;		}		PortP = (p->RIOPortp[PortTty.port]);		RIOParam(PortP, CONFIG, PortP->State & RIO_MODEM, OK_TO_SLEEP);		return retval;	case RIO_SET_PORT_PARAMS:		rio_dprintk(RIO_DEBUG_CTRL, "Set port params\n");		if (copy_from_user(&PortParams, arg, sizeof(PortParams))) {			p->RIOError.Error = COPYIN_FAILED;			return -EFAULT;		}		if (PortParams.Port >= (ushort) RIO_PORTS) {			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;			return -ENXIO;		}		PortP = (p->RIOPortp[PortParams.Port]);		rio_spin_lock_irqsave(&PortP->portSem, flags);		PortP->Config = PortParams.Config;		rio_spin_unlock_irqrestore(&PortP->portSem, flags);		return retval;	case RIO_GET_PORT_STATS:		rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n");		if (copy_from_user(&portStats, arg, sizeof(struct portStats))) {			p->RIOError.Error = COPYIN_FAILED;			return -EFAULT;		}		if (portStats.port >= RIO_PORTS) {			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;			return -ENXIO;		}		PortP = (p->RIOPortp[portStats.port]);		portStats.gather = PortP->statsGather;		portStats.txchars = PortP->txchars;		portStats.rxchars = PortP->rxchars;		portStats.opens = PortP->opens;		portStats.closes = PortP->closes;		portStats.ioctls = PortP->ioctls;		if (copy_to_user(arg, &portStats, sizeof(struct portStats))) {			p->RIOError.Error = COPYOUT_FAILED;			return -EFAULT;		}		return retval;	case RIO_RESET_PORT_STATS:		port = (unsigned long) arg;		rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n");		if (port >= RIO_PORTS) {			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;			return -ENXIO;		}		PortP = (p->RIOPortp[port]);		rio_spin_lock_irqsave(&PortP->portSem, flags);		PortP->txchars = 0;		PortP->rxchars = 0;		PortP->opens = 0;		PortP->closes = 0;		PortP->ioctls = 0;		rio_spin_unlock_irqrestore(&PortP->portSem, flags);		return retval;	case RIO_GATHER_PORT_STATS:		rio_dprintk(RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n");		if (copy_from_user(&portStats, arg, sizeof(struct portStats))) {			p->RIOError.Error = COPYIN_FAILED;			return -EFAULT;		}		if (portStats.port >= RIO_PORTS) {			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;			return -ENXIO;		}		PortP = (p->RIOPortp[portStats.port]);		rio_spin_lock_irqsave(&PortP->portSem, flags);		PortP->statsGather = portStats.gather;		rio_spin_unlock_irqrestore(&PortP->portSem, flags);		return retval;	case RIO_READ_CONFIG:		rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n");		if (copy_to_user(arg, &p->RIOConf, sizeof(struct Conf))) {			p->RIOError.Error = COPYOUT_FAILED;			return -EFAULT;		}		return retval;	case RIO_SET_CONFIG:		rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_CONFIG\n");		if (!su) {			p->RIOError.Error = NOT_SUPER_USER;			return -EPERM;		}		if (copy_from_user(&p->RIOConf, arg, sizeof(struct Conf))) {			p->RIOError.Error = COPYIN_FAILED;			return -EFAULT;		}		/*		 ** move a few value around		 */		for (Host = 0; Host < p->RIONumHosts; Host++)			if ((p->RIOHosts[Host].Flags & RUN_STATE) == RC_RUNNING)				writew(p->RIOConf.Timer, &p->RIOHosts[Host].ParmMapP->timer);		return retval;	case RIO_START_POLLER:		rio_dprintk(RIO_DEBUG_CTRL, "RIO_START_POLLER\n");		return -EINVAL;	case RIO_STOP_POLLER:		rio_dprintk(RIO_DEBUG_CTRL, "RIO_STOP_POLLER\n");		if (!su) {			p->RIOError.Error = NOT_SUPER_USER;			return -EPERM;		}		p->RIOPolling = NOT_POLLING;		return retval;	case RIO_SETDEBUG:	case RIO_GETDEBUG:		rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n");		if (copy_from_user(&DebugCtrl, arg, sizeof(DebugCtrl))) {			p->RIOError.Error = COPYIN_FAILED;

⌨️ 快捷键说明

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