rioctrl.c

来自「linux2.6.16版本」· C语言 代码 · 共 1,644 行 · 第 1/4 页

C
1,644
字号
		if (!su) {			rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS !Root\n");			p->RIOError.Error = NOT_SUPER_USER;			return -EPERM;		}		if (copyout((caddr_t) p->RIOBindTab, (int) arg, (sizeof(ulong) * MAX_RTA_BINDINGS)) == COPYFAIL) {			rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n");			p->RIOError.Error = COPYOUT_FAILED;			return -EFAULT;		}		return 0;	case RIO_PUT_BINDINGS:		/*		 ** Receive a bindings table, containing unique numbers of RTAs owned		 ** by this system		 */		rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS\n");		if (!su) {			rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS !Root\n");			p->RIOError.Error = NOT_SUPER_USER;			return -EPERM;		}		if (copyin((int) arg, (caddr_t) & p->RIOBindTab[0], (sizeof(ulong) * MAX_RTA_BINDINGS)) == COPYFAIL) {			rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n");			p->RIOError.Error = COPYIN_FAILED;			return -EFAULT;		}		return 0;	case RIO_BIND_RTA:		{			int EmptySlot = -1;			/*			 ** Bind this RTA to host, so that it will be booted by			 ** host in 'boot owned RTAs' mode.			 */			rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA\n");			if (!su) {				rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA !Root\n");				p->RIOError.Error = NOT_SUPER_USER;				return -EPERM;			}			for (Entry = 0; Entry < MAX_RTA_BINDINGS; Entry++) {				if ((EmptySlot == -1) && (p->RIOBindTab[Entry] == 0L))					EmptySlot = Entry;				else if (p->RIOBindTab[Entry] == (int) arg) {					/*					 ** Already exists - delete					 */					p->RIOBindTab[Entry] = 0L;					rio_dprintk(RIO_DEBUG_CTRL, "Removing Rta %x from p->RIOBindTab\n", (int) arg);					return 0;				}			}			/*			 ** Dosen't exist - add			 */			if (EmptySlot != -1) {				p->RIOBindTab[EmptySlot] = (int) arg;				rio_dprintk(RIO_DEBUG_CTRL, "Adding Rta %x to p->RIOBindTab\n", (int) arg);			} else {				rio_dprintk(RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %x not added\n", (int) arg);				return -ENOMEM;			}			return 0;		}	case RIO_RESUME:		rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME\n");		port = (uint) 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 (copyin((int) arg, (caddr_t) & MapEnt, sizeof(MapEnt))		    == COPYFAIL) {			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 (copyin((int) arg, (caddr_t) & MapEnt, sizeof(MapEnt))		    == COPYFAIL) {			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 (copyin((int) arg, (caddr_t) & MapEnt, sizeof(MapEnt))		    == COPYFAIL) {			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:		/*		 ** 09.12.1998 ARG - ESIL 0776 part fix		 ** A customer was using this to get the RTAs		 ** connect/disconnect status.		 ** RIOConCon() had been botched use RIOHalted		 ** to keep track of RTA connections and		 ** disconnections. That has been changed and		 ** RIORtaDisCons in the rio_info struct now		 ** does the job. So we need to return the value		 ** of RIORtaCons instead of RIOHalted.		 **		 if (copyout((caddr_t)&p->RIOHalted,(int)arg,		 sizeof(uint))==COPYFAIL) {		 **		 */		if (copyout((caddr_t) & p->RIORtaDisCons, (int) arg, sizeof(uint)) == COPYFAIL) {			p->RIOError.Error = COPYOUT_FAILED;			return -EFAULT;		}		return 0;	case RIO_LAST_ERROR:		if (copyout((caddr_t) & p->RIOError, (int) arg, sizeof(struct Error)) == COPYFAIL)			return -EFAULT;		return 0;	case RIO_GET_LOG:		rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_LOG\n");		return -EINVAL;	case RIO_GET_MODTYPE:		if (copyin((int) arg, (caddr_t) & port, sizeof(uint)) == COPYFAIL) {			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 (copyout((caddr_t) & port, (int) arg, sizeof(uint)) == COPYFAIL) {			p->RIOError.Error = COPYOUT_FAILED;			return -EFAULT;		}		return (0);		/*		 ** 02.03.1999 ARG - ESIL 0820 fix		 ** We are no longer using "Boot Mode", so these ioctls		 ** are not required :		 **		 case RIO_GET_BOOT_MODE :		 rio_dprint(RIO_DEBUG_CTRL, ("Get boot mode - %x\n", p->RIOBootMode));		 **		 ** Return boot state of system - BOOT_ALL, BOOT_OWN or BOOT_NONE		 **		 if (copyout((caddr_t)&p->RIOBootMode, (int)arg,		 sizeof(p->RIOBootMode)) == COPYFAIL) {		 p->RIOError.Error = COPYOUT_FAILED;		 return -EFAULT;		 }		 return(0);		 case RIO_SET_BOOT_MODE :		 p->RIOBootMode = (uint) arg;		 rio_dprint(RIO_DEBUG_CTRL, ("Set boot mode to 0x%x\n", p->RIOBootMode));		 return(0);		 **		 ** End ESIL 0820 fix		 */	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 (copyin((int) arg, (caddr_t) & PortSetup, sizeof(PortSetup))		    == COPYFAIL) {			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) {			cprintf("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 (copyin((int) arg, (caddr_t) & PortSetup, sizeof(PortSetup))		    == COPYFAIL) {			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;		bcopy(p->RIOPortp[port]->Xprint.XpOn, PortSetup.XpOn, MAX_XP_CTRL_LEN);		bcopy(p->RIOPortp[port]->Xprint.XpOff, PortSetup.XpOff, MAX_XP_CTRL_LEN);		PortSetup.XpOn[MAX_XP_CTRL_LEN - 1] = '\0';		PortSetup.XpOff[MAX_XP_CTRL_LEN - 1] = '\0';		if (copyout((caddr_t) & PortSetup, (int) arg, sizeof(PortSetup))		    == COPYFAIL) {			p->RIOError.Error = COPYOUT_FAILED;			return -EFAULT;		}		return retval;	case RIO_GET_PORT_PARAMS:		rio_dprintk(RIO_DEBUG_CTRL, "Get port params\n");		if (copyin((int) arg, (caddr_t) & PortParams, sizeof(struct PortParams)) == COPYFAIL) {			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 (copyout((caddr_t) & PortParams, (int) arg, sizeof(struct PortParams)) == COPYFAIL) {			p->RIOError.Error = COPYOUT_FAILED;			return -EFAULT;		}		return retval;	case RIO_GET_PORT_TTY:		rio_dprintk(RIO_DEBUG_CTRL, "Get port tty\n");		if (copyin((int) arg, (caddr_t) & PortTty, sizeof(struct PortTty))		    == COPYFAIL) {			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 (copyout((caddr_t) & PortTty, (int) arg, sizeof(struct PortTty)) == COPYFAIL) {			p->RIOError.Error = COPYOUT_FAILED;			return -EFAULT;		}		return retval;	case RIO_SET_PORT_TTY:		if (copyin((int) arg, (caddr_t) & PortTty, sizeof(struct PortTty)) == COPYFAIL) {			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 (copyin((int) arg, (caddr_t) & PortParams, sizeof(PortParams))		    == COPYFAIL) {			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 (copyin((int) arg, (caddr_t) & portStats, sizeof(struct portStats)) == COPYFAIL) {			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 (copyout((caddr_t) & portStats, (int) arg, sizeof(struct portStats)) == COPYFAIL) {			p->RIOError.Error = COPYOUT_FAILED;			return -EFAULT;		}		return retval;	case RIO_RESET_PORT_STATS:		port = (uint) 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);

⌨️ 快捷键说明

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