rioctrl.c
来自「LINUX 2.6.17.4的源码」· C语言 代码 · 共 1,498 行 · 第 1/4 页
C
1,498 行
return -EFAULT; } if (DebugCtrl.SysPort == NO_PORT) { if (cmd == RIO_SETDEBUG) { if (!su) { p->RIOError.Error = NOT_SUPER_USER; return -EPERM; } p->rio_debug = DebugCtrl.Debug; p->RIODebugWait = DebugCtrl.Wait; rio_dprintk(RIO_DEBUG_CTRL, "Set global debug to 0x%x set wait to 0x%x\n", p->rio_debug, p->RIODebugWait); } else { rio_dprintk(RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n", p->rio_debug, p->RIODebugWait); DebugCtrl.Debug = p->rio_debug; DebugCtrl.Wait = p->RIODebugWait; if (copy_to_user(arg, &DebugCtrl, sizeof(DebugCtrl))) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort); p->RIOError.Error = COPYOUT_FAILED; return -EFAULT; } } } else if (DebugCtrl.SysPort >= RIO_PORTS && DebugCtrl.SysPort != NO_PORT) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort); p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; return -ENXIO; } else if (cmd == RIO_SETDEBUG) { if (!su) { p->RIOError.Error = NOT_SUPER_USER; return -EPERM; } rio_spin_lock_irqsave(&PortP->portSem, flags); p->RIOPortp[DebugCtrl.SysPort]->Debug = DebugCtrl.Debug; rio_spin_unlock_irqrestore(&PortP->portSem, flags); rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug); } else { rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug); DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug; if (copy_to_user(arg, &DebugCtrl, sizeof(DebugCtrl))) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n"); p->RIOError.Error = COPYOUT_FAILED; return -EFAULT; } } return retval; case RIO_VERSID: /* ** Enquire about the release and version. ** We return MAX_VERSION_LEN bytes, being a ** textual null terminated string. */ rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID\n"); if (copy_to_user(arg, RIOVersid(), sizeof(struct rioVersion))) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID: Bad copy to user space (host=%d)\n", Host); p->RIOError.Error = COPYOUT_FAILED; return -EFAULT; } return retval; case RIO_NUM_HOSTS: /* ** Enquire as to the number of hosts located ** at init time. */ rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n"); if (copy_to_user(arg, &p->RIONumHosts, sizeof(p->RIONumHosts))) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n"); p->RIOError.Error = COPYOUT_FAILED; return -EFAULT; } return retval; case RIO_HOST_FOAD: /* ** Kill host. This may not be in the final version... */ rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD %ld\n", (unsigned long) arg); if (!su) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n"); p->RIOError.Error = NOT_SUPER_USER; return -EPERM; } p->RIOHalted = 1; p->RIOSystemUp = 0; for (Host = 0; Host < p->RIONumHosts; Host++) { (void) RIOBoardTest(p->RIOHosts[Host].PaddrP, p->RIOHosts[Host].Caddr, p->RIOHosts[Host].Type, p->RIOHosts[Host].Slot); memset(&p->RIOHosts[Host].Flags, 0, ((char *) &p->RIOHosts[Host].____end_marker____) - ((char *) &p->RIOHosts[Host].Flags)); p->RIOHosts[Host].Flags = RC_WAITING; } RIOFoadWakeup(p); p->RIONumBootPkts = 0; p->RIOBooting = 0; printk("HEEEEELP!\n"); for (loop = 0; loop < RIO_PORTS; loop++) { spin_lock_init(&p->RIOPortp[loop]->portSem); p->RIOPortp[loop]->InUse = NOT_INUSE; } p->RIOSystemUp = 0; return retval; case RIO_DOWNLOAD: rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD\n"); if (!su) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Not super user\n"); p->RIOError.Error = NOT_SUPER_USER; return -EPERM; } if (copy_from_user(&DownLoad, arg, sizeof(DownLoad))) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n"); p->RIOError.Error = COPYIN_FAILED; return -EFAULT; } rio_dprintk(RIO_DEBUG_CTRL, "Copied in download code for product code 0x%x\n", DownLoad.ProductCode); /* ** It is important that the product code is an unsigned object! */ if (DownLoad.ProductCode > MAX_PRODUCT) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passed\n", DownLoad.ProductCode); p->RIOError.Error = NO_SUCH_PRODUCT; return -ENXIO; } /* ** do something! */ retval = (*(RIOBootTable[DownLoad.ProductCode])) (p, &DownLoad); /* <-- Panic */ p->RIOHalted = 0; /* ** and go back, content with a job well completed. */ return retval; case RIO_PARMS: { unsigned int host; if (copy_from_user(&host, arg, sizeof(host))) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); p->RIOError.Error = COPYIN_FAILED; return -EFAULT; } /* ** Fetch the parmmap */ rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS\n"); if (copy_to_user(arg, p->RIOHosts[host].ParmMapP, sizeof(PARM_MAP))) { p->RIOError.Error = COPYOUT_FAILED; rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n"); return -EFAULT; } } return retval; case RIO_HOST_REQ: rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ\n"); if (copy_from_user(&HostReq, arg, sizeof(HostReq))) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); p->RIOError.Error = COPYIN_FAILED; return -EFAULT; } if (HostReq.HostNum >= p->RIONumHosts) { p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Illegal host number %d\n", HostReq.HostNum); return -ENXIO; } rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostReq.HostNum); if (copy_to_user(HostReq.HostP, &p->RIOHosts[HostReq.HostNum], sizeof(struct Host))) { p->RIOError.Error = COPYOUT_FAILED; rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Bad copy to user space\n"); return -EFAULT; } return retval; case RIO_HOST_DPRAM: rio_dprintk(RIO_DEBUG_CTRL, "Request for DPRAM\n"); if (copy_from_user(&HostDpRam, arg, sizeof(HostDpRam))) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n"); p->RIOError.Error = COPYIN_FAILED; return -EFAULT; } if (HostDpRam.HostNum >= p->RIONumHosts) { p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Illegal host number %d\n", HostDpRam.HostNum); return -ENXIO; } rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostDpRam.HostNum); if (p->RIOHosts[HostDpRam.HostNum].Type == RIO_PCI) { int off; /* It's hardware like this that really gets on my tits. */ static unsigned char copy[sizeof(struct DpRam)]; for (off = 0; off < sizeof(struct DpRam); off++) copy[off] = readb(&p->RIOHosts[HostDpRam.HostNum].Caddr[off]); if (copy_to_user(HostDpRam.DpRamP, copy, sizeof(struct DpRam))) { p->RIOError.Error = COPYOUT_FAILED; rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); return -EFAULT; } } else if (copy_to_user(HostDpRam.DpRamP, p->RIOHosts[HostDpRam.HostNum].Caddr, sizeof(struct DpRam))) { p->RIOError.Error = COPYOUT_FAILED; rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); return -EFAULT; } return retval; case RIO_SET_BUSY: rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY\n"); if ((unsigned long) arg > 511) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %ld\n", (unsigned long) arg); p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; return -EINVAL; } rio_spin_lock_irqsave(&PortP->portSem, flags); p->RIOPortp[(unsigned long) arg]->State |= RIO_BUSY; rio_spin_unlock_irqrestore(&PortP->portSem, flags); return retval; case RIO_HOST_PORT: /* ** The daemon want port information ** (probably for debug reasons) */ rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT\n"); if (copy_from_user(&PortReq, arg, sizeof(PortReq))) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n"); p->RIOError.Error = COPYIN_FAILED; return -EFAULT; } if (PortReq.SysPort >= RIO_PORTS) { /* SysPort is unsigned */ rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Illegal port number %d\n", PortReq.SysPort); p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; return -ENXIO; } rio_dprintk(RIO_DEBUG_CTRL, "Request for port %d\n", PortReq.SysPort); if (copy_to_user(PortReq.PortP, p->RIOPortp[PortReq.SysPort], sizeof(struct Port))) { p->RIOError.Error = COPYOUT_FAILED; rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Bad copy to user space\n"); return -EFAULT; } return retval; case RIO_HOST_RUP: /* ** The daemon want rup information ** (probably for debug reasons) */ rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP\n"); if (copy_from_user(&RupReq, arg, sizeof(RupReq))) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n"); p->RIOError.Error = COPYIN_FAILED; return -EFAULT; } if (RupReq.HostNum >= p->RIONumHosts) { /* host is unsigned */ rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal host number %d\n", RupReq.HostNum); p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; return -ENXIO; } if (RupReq.RupNum >= MAX_RUP + LINKS_PER_UNIT) { /* eek! */ rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal rup number %d\n", RupReq.RupNum); p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; return -EINVAL; } HostP = &p->RIOHosts[RupReq.HostNum]; if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Host %d not running\n", RupReq.HostNum); p->RIOError.Error = HOST_NOT_RUNNING; return -EIO; } rio_dprintk(RIO_DEBUG_CTRL, "Request for rup %d from host %d\n", RupReq.RupNum, RupReq.HostNum); if (copy_to_user(HostP->UnixRups[RupReq.RupNum].RupP, RupReq.RupP, sizeof(struct RUP))) { p->RIOError.Error = COPYOUT_FAILED; rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n"); return -EFAULT; } return retval; case RIO_HOST_LPB: /* ** The daemon want lpb information ** (probably for debug reasons) */ rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB\n"); if (copy_from_user(&LpbReq, arg, sizeof(LpbReq))) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n"); p->RIOError.Error = COPYIN_FAILED; return -EFAULT; } if (LpbReq.Host >= p->RIONumHosts) { /* host is unsigned */ rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal host number %d\n", LpbReq.Host); p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; return -ENXIO; } if (LpbReq.Link >= LINKS_PER_UNIT) { /* eek! */ rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %d\n", LpbReq.Link); p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE; return -EINVAL; } HostP = &p->RIOHosts[LpbReq.Host]; if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not running\n", LpbReq.Host); p->RIOError.Error = HOST_NOT_RUNNING; return -EIO; } rio_dprintk(RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n", LpbReq.Link, LpbReq.Host); if (copy_to_user(LpbReq.LpbP, &HostP->LinkStrP[LpbReq.Link], sizeof(struct LPB))) { rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n"); p->RIOError.Error = COPYOUT_FAILED; return -EFAULT; } return retval; /* ** Here 3 IOCTL's that allow us to change the way in which ** rio logs errors. send them just to syslog or send them ** to both syslog and console or send them to just the console. ** ** See RioStrBuf() in util.c for the other half. */ case RIO_SYSLOG_ONLY: p->RIOPrintLogState = PRINT_TO_LOG; /* Just syslog */ return 0; case RIO_SYSLOG_CONS: p->RIOPrintLogState = PRINT_TO_LOG_CONS; /* syslog and console */ return 0; case RIO_CONS_ONLY: p->RIOPrintLogState = PRINT_TO_CONS; /* Just console */ return 0; case RIO_SIGNALS_ON: if (p->RIOSignalProcess) { p->RIOError.Error = SIGNALS_ALREADY_SET; return -EBUSY; } /* FIXME: PID tracking */ p->RIOSignalProcess = current->pid; p->RIOPrintDisabled = DONT_PRINT; return retval; case RIO_SIGNALS_OFF: if (p->RIOSignalProcess != current->pid) { p->RIOError.Error = NOT_RECEIVING_PROCESS; return -EPERM; } rio_dprintk(RIO_DEBUG_CTRL, "Clear signal process to zero\n"); p->RIOSignalProcess = 0; return retval; case RIO_SET_BYTE_MODE: for (Host = 0; Host < p->RIONumHosts; Host++) if (p->RIOHosts[Host].Type == RIO_AT) p->RIOHosts[Host].Mode &= ~WORD_OPERATION; return retval; case RIO_SET_WORD_MODE: for (Host = 0; Host < p->RIONumHosts; Host++) if (p->RIOHosts[Host].Type == RIO_AT) p->RIOHosts[Host].Mode |= WORD_OPERATION; return retval; case RIO_SET_FAST_BUS: for (Host = 0; Host < p->RIONumHosts; Host++) if (p->RIOHosts[Host].Type == RIO_AT) p->RIOHosts[Host].Mode |= FAST_AT_BUS;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?