rioctrl.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:59k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2. ** -----------------------------------------------------------------------------
  3. **
  4. **  Perle Specialix driver for Linux
  5. **  Ported from existing RIO Driver for SCO sources.
  6.  *
  7.  *  (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
  8.  *
  9.  *      This program is free software; you can redistribute it and/or modify
  10.  *      it under the terms of the GNU General Public License as published by
  11.  *      the Free Software Foundation; either version 2 of the License, or
  12.  *      (at your option) any later version.
  13.  *
  14.  *      This program is distributed in the hope that it will be useful,
  15.  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  *      GNU General Public License for more details.
  18.  *
  19.  *      You should have received a copy of the GNU General Public License
  20.  *      along with this program; if not, write to the Free Software
  21.  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. **
  23. ** Module : rioctrl.c
  24. ** SID : 1.3
  25. ** Last Modified : 11/6/98 10:33:42
  26. ** Retrieved : 11/6/98 10:33:49
  27. **
  28. **  ident @(#)rioctrl.c 1.3
  29. **
  30. ** -----------------------------------------------------------------------------
  31. */
  32. #ifdef SCCS_LABELS
  33. static char *_rioctrl_c_sccs_ = "@(#)rioctrl.c 1.3";
  34. #endif
  35. #define __NO_VERSION__
  36. #include <linux/module.h>
  37. #include <linux/slab.h>
  38. #include <linux/errno.h>
  39. #include <asm/io.h>
  40. #include <asm/system.h>
  41. #include <asm/string.h>
  42. #include <asm/semaphore.h>
  43. #include <asm/uaccess.h>
  44. #include <linux/termios.h>
  45. #include <linux/serial.h>
  46. #include <linux/compatmac.h>
  47. #include <linux/generic_serial.h>
  48. #include "linux_compat.h"
  49. #include "rio_linux.h"
  50. #include "typdef.h"
  51. #include "pkt.h"
  52. #include "daemon.h"
  53. #include "rio.h"
  54. #include "riospace.h"
  55. #include "top.h"
  56. #include "cmdpkt.h"
  57. #include "map.h"
  58. #include "riotypes.h"
  59. #include "rup.h"
  60. #include "port.h"
  61. #include "riodrvr.h"
  62. #include "rioinfo.h"
  63. #include "func.h"
  64. #include "errors.h"
  65. #include "pci.h"
  66. #include "parmmap.h"
  67. #include "unixrup.h"
  68. #include "board.h"
  69. #include "host.h"
  70. #include "error.h"
  71. #include "phb.h"
  72. #include "link.h"
  73. #include "cmdblk.h"
  74. #include "route.h"
  75. #include "control.h"
  76. #include "cirrus.h"
  77. #include "rioioctl.h"
  78. static struct LpbReq  LpbReq;
  79. static struct RupReq  RupReq;
  80. static struct PortReq PortReq;
  81. static struct HostReq HostReq;
  82. static struct HostDpRam HostDpRam;
  83. static struct DebugCtrl DebugCtrl;
  84. static struct Map  MapEnt;
  85. static struct PortSetup PortSetup;
  86. static struct DownLoad DownLoad;
  87. static struct SendPack  SendPack;
  88. /* static struct StreamInfo StreamInfo; */
  89. /* static char modemtable[RIO_PORTS]; */
  90. static struct SpecialRupCmd SpecialRupCmd;
  91. static struct PortParams PortParams;
  92. static struct portStats portStats;
  93. static struct SubCmdStruct {
  94. ushort Host;
  95. ushort Rup;
  96. ushort Port;
  97. ushort Addr;
  98. } SubCmd;
  99. struct PortTty {
  100. uint port;
  101. struct ttystatics Tty;
  102. };
  103. static struct PortTty PortTty;
  104. typedef struct ttystatics TERMIO;
  105. /*
  106. ** This table is used when the config.rio downloads bin code to the
  107. ** driver. We index the table using the product code, 0-F, and call
  108. ** the function pointed to by the entry, passing the information
  109. ** about the boot.
  110. ** The RIOBootCodeUNKNOWN entry is there to politely tell the calling
  111. ** process to bog off.
  112. */
  113. static int 
  114. (*RIOBootTable[MAX_PRODUCT])(struct rio_info *, struct DownLoad *) =
  115. {
  116. /* 0 */ RIOBootCodeHOST, /* Host Card */
  117. /* 1 */ RIOBootCodeRTA, /* RTA */
  118. };
  119. #define drv_makedev(maj, min) ((((uint) maj & 0xff) << 8) | ((uint) min & 0xff))
  120. #ifdef linux
  121. int copyin (int arg, caddr_t dp, int siz)
  122. {
  123.   int rv;
  124.   rio_dprintk (RIO_DEBUG_CTRL, "Copying %d bytes from user %p to %p.n", siz, (void *)arg, dp);
  125.   rv = copy_from_user (dp, (void *)arg, siz);
  126.   if (rv < 0) return COPYFAIL;
  127.   else return rv;
  128. }
  129. int copyout (caddr_t dp, int arg, int siz)
  130. {
  131.   int rv;
  132.   rio_dprintk (RIO_DEBUG_CTRL, "Copying %d bytes to user %p from %p.n", siz, (void *)arg, dp);
  133.   rv = copy_to_user ((void *)arg, dp, siz);
  134.   if (rv < 0) return COPYFAIL;
  135.   else return rv;
  136. }
  137. #else
  138. int
  139. copyin(arg, dp, siz)
  140. int arg;
  141. caddr_t dp;
  142. int siz; 
  143. {
  144. if (rbounds ((unsigned long) arg) >= siz) {
  145. bcopy ( arg, dp, siz );
  146. return OK;
  147. } else
  148. return ( COPYFAIL );
  149. }
  150. int
  151. copyout (dp, arg, siz)
  152. caddr_t dp;
  153. int arg;
  154. int siz;
  155. {
  156. if (wbounds ((unsigned long) arg) >=  siz ) {
  157. bcopy ( dp, arg, siz );
  158. return OK;
  159. } else
  160. return ( COPYFAIL );
  161. }
  162. #endif
  163. int
  164. riocontrol(p, dev, cmd, arg, su)
  165. struct rio_info * p;
  166. dev_t dev;
  167. int cmd;
  168. caddr_t arg;
  169. int su;
  170. {
  171. uint Host; /* leave me unsigned! */
  172. uint port; /* and me! */
  173. struct Host *HostP;
  174. ushort loop;
  175. int Entry;
  176. struct Port *PortP;
  177. PKT *PacketP;
  178. int retval = 0;
  179. unsigned long flags;
  180. func_enter ();
  181. /* Confuse teh compiler to think that we've initialized these */
  182. Host=0;
  183. PortP = NULL;
  184. rio_dprintk (RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: 0x%xn", cmd, (int)arg);
  185. switch (cmd) {
  186. /*
  187. ** RIO_SET_TIMER
  188. **
  189. ** Change the value of the host card interrupt timer.
  190. ** If the host card number is -1 then all host cards are changed
  191. ** otherwise just the specified host card will be changed.
  192. */
  193. case RIO_SET_TIMER:
  194. rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_TIMER to %dmsn", (uint)arg);
  195. {
  196. int host, value;
  197. host = (uint)arg >> 16;
  198. value = (uint)arg & 0x0000ffff;
  199. if (host == -1) {
  200. for (host = 0; host < p->RIONumHosts; host++) {
  201. if (p->RIOHosts[host].Flags == RC_RUNNING) {
  202. WWORD(p->RIOHosts[host].ParmMapP->timer , value);
  203. }
  204. }
  205. } else if (host >= p->RIONumHosts) {
  206. return EINVAL;
  207. } else {
  208. if ( p->RIOHosts[host].Flags == RC_RUNNING ) {
  209. WWORD(p->RIOHosts[host].ParmMapP->timer , value);
  210. }
  211. }
  212. }
  213. return 0;
  214. case RIO_IDENTIFY_DRIVER:
  215. /*
  216. ** 15.10.1998 ARG - ESIL 0760 part fix
  217. ** Added driver ident string output.
  218. **
  219. #ifndef __THIS_RELEASE__
  220. #warning Driver Version string not defined !
  221. #endif
  222. cprintf("%s %s %s %sn",
  223. RIO_DRV_STR,
  224. __THIS_RELEASE__,
  225. __DATE__, __TIME__ );
  226. return 0;
  227. case RIO_DISPLAY_HOST_CFG:
  228. **
  229. ** 15.10.1998 ARG - ESIL 0760 part fix
  230. ** Added driver host card ident string output.
  231. **
  232. ** Note that the only types currently supported
  233. ** are ISA and PCI. Also this driver does not
  234. ** (yet) distinguish between the Old PCI card
  235. ** and the Jet PCI card. In fact I think this
  236. ** driver only supports JET PCI !
  237. **
  238. for (Host = 0; Host < p->RIONumHosts; Host++)
  239. {
  240. HostP = &(p->RIOHosts[Host]);
  241. switch ( HostP->Type )
  242. {
  243.     case RIO_AT :
  244. strcpy( host_type, RIO_AT_HOST_STR );
  245. break;
  246.     case RIO_PCI :
  247. strcpy( host_type, RIO_PCI_HOST_STR );
  248. break;
  249.     default :
  250. strcpy( host_type, "Unknown" );
  251. break;
  252. }
  253. cprintf(
  254.   "RIO Host %d - Type:%s Addr:%X IRQ:%dn",
  255. Host, host_type,
  256. (uint)HostP->PaddrP,
  257. (int)HostP->Ivec - 32  );
  258. }
  259. return 0;
  260. **
  261. */
  262. case RIO_FOAD_RTA:
  263. rio_dprintk (RIO_DEBUG_CTRL, "RIO_FOAD_RTAn");
  264. return RIOCommandRta(p, (uint)arg, RIOFoadRta);
  265. case RIO_ZOMBIE_RTA:
  266. rio_dprintk (RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTAn");
  267. return RIOCommandRta(p, (uint)arg, RIOZombieRta);
  268. case RIO_IDENTIFY_RTA:
  269. rio_dprintk (RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTAn");
  270. return RIOIdentifyRta(p, arg);
  271. case RIO_KILL_NEIGHBOUR:
  272. rio_dprintk (RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOURn");
  273. return RIOKillNeighbour(p, arg);
  274. case SPECIAL_RUP_CMD:
  275. {
  276. struct CmdBlk *CmdBlkP;
  277. rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMDn");
  278. if (copyin((int)arg, (caddr_t)&SpecialRupCmd, 
  279. sizeof(SpecialRupCmd)) == COPYFAIL ) {
  280. rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failedn");
  281. p->RIOError.Error = COPYIN_FAILED;
  282.   return EFAULT;
  283. }
  284. CmdBlkP = RIOGetCmdBlk();
  285. if ( !CmdBlkP ) {
  286. rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD GetCmdBlk failedn");
  287. return ENXIO;
  288. }
  289. CmdBlkP->Packet = SpecialRupCmd.Packet;
  290. if ( SpecialRupCmd.Host >= p->RIONumHosts )
  291. SpecialRupCmd.Host = 0;
  292. rio_dprintk (RIO_DEBUG_CTRL, "Queue special rup command for host %d rup %dn",
  293. SpecialRupCmd.Host, SpecialRupCmd.RupNum);
  294. if (RIOQueueCmdBlk(&p->RIOHosts[SpecialRupCmd.Host], 
  295. SpecialRupCmd.RupNum, CmdBlkP) == RIO_FAIL) {
  296. cprintf("FAILED TO QUEUE SPECIAL RUP COMMANDn");
  297. }
  298. return 0;
  299. }
  300. case RIO_DEBUG_MEM:
  301. #ifdef DEBUG_MEM_SUPPORT
  302. RIO_DEBUG_CTRL,  if (su)
  303. return rio_RIODebugMemory(RIO_DEBUG_CTRL, arg);
  304. else
  305. #endif
  306. return EPERM;
  307. case RIO_ALL_MODEM:
  308. rio_dprintk (RIO_DEBUG_CTRL, "RIO_ALL_MODEMn");
  309. p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
  310. return EINVAL;
  311. case RIO_GET_TABLE:
  312. /*
  313. ** Read the routing table from the device driver to user space
  314. */
  315. rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_TABLEn");
  316. if ((retval = RIOApel(p)) != 0)
  317.   return retval;
  318. if (copyout((caddr_t)p->RIOConnectTable, (int)arg,
  319. TOTAL_MAP_ENTRIES*sizeof(struct Map)) == COPYFAIL) {
  320.   rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failedn");
  321.   p->RIOError.Error = COPYOUT_FAILED;
  322.   return EFAULT;
  323. }
  324. {
  325. int entry;
  326. rio_dprintk (RIO_DEBUG_CTRL,  "*****nMAP ENTRIESn");
  327. for ( entry=0; entry<TOTAL_MAP_ENTRIES; entry++ )
  328. {
  329.   if ((p->RIOConnectTable[entry].ID == 0) &&
  330.       (p->RIOConnectTable[entry].HostUniqueNum == 0) &&
  331.       (p->RIOConnectTable[entry].RtaUniqueNum == 0)) continue;
  332.       
  333. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.HostUniqueNum = 0x%xn", entry, p->RIOConnectTable[entry].HostUniqueNum );
  334. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.RtaUniqueNum = 0x%xn", entry, p->RIOConnectTable[entry].RtaUniqueNum );
  335. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.ID = 0x%xn", entry, p->RIOConnectTable[entry].ID );
  336. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.ID2 = 0x%xn", entry, p->RIOConnectTable[entry].ID2 );
  337. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Flags = 0x%xn", entry, (int)p->RIOConnectTable[entry].Flags );
  338. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.SysPort = 0x%xn", entry, (int)p->RIOConnectTable[entry].SysPort );
  339. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[0].Unit = %xn", entry, p->RIOConnectTable[entry].Topology[0].Unit );
  340. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[0].Link = %xn", entry, p->RIOConnectTable[entry].Topology[0].Link );
  341. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[1].Unit = %xn", entry, p->RIOConnectTable[entry].Topology[1].Unit );
  342. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[1].Link = %xn", entry, p->RIOConnectTable[entry].Topology[1].Link );
  343. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[2].Unit = %xn", entry, p->RIOConnectTable[entry].Topology[2].Unit );
  344. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[2].Link = %xn", entry, p->RIOConnectTable[entry].Topology[2].Link );
  345. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[3].Unit = %xn", entry, p->RIOConnectTable[entry].Topology[3].Unit );
  346. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[4].Link = %xn", entry, p->RIOConnectTable[entry].Topology[3].Link );
  347. rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Name = %sn", entry, p->RIOConnectTable[entry].Name );
  348. }
  349. rio_dprintk (RIO_DEBUG_CTRL,  "*****nEND MAP ENTRIESn");
  350. }
  351. p->RIOQuickCheck = NOT_CHANGED; /* a table has been gotten */
  352. return 0;
  353. case RIO_PUT_TABLE:
  354. /*
  355. ** Write the routing table to the device driver from user space
  356. */
  357. rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLEn");
  358. if ( !su ) {
  359.   rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE !Rootn");
  360.   p->RIOError.Error = NOT_SUPER_USER;
  361.   return EPERM;
  362. }
  363. if ( copyin((int)arg, (caddr_t)&p->RIOConnectTable[0], 
  364. TOTAL_MAP_ENTRIES*sizeof(struct Map) ) == COPYFAIL ) {
  365.   rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failedn");
  366.   p->RIOError.Error = COPYIN_FAILED;
  367.   return EFAULT;
  368. }
  369. /*
  370. ***********************************
  371. {
  372. int entry;
  373. rio_dprint(RIO_DEBUG_CTRL,  ("*****nMAP ENTRIESn") );
  374. for ( entry=0; entry<TOTAL_MAP_ENTRIES; entry++ )
  375. {
  376. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.HostUniqueNum = 0x%xn", entry, p->RIOConnectTable[entry].HostUniqueNum ) );
  377. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.RtaUniqueNum = 0x%xn", entry, p->RIOConnectTable[entry].RtaUniqueNum ) );
  378. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.ID = 0x%xn", entry, p->RIOConnectTable[entry].ID ) );
  379. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.ID2 = 0x%xn", entry, p->RIOConnectTable[entry].ID2 ) );
  380. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Flags = 0x%xn", entry, p->RIOConnectTable[entry].Flags ) );
  381. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.SysPort = 0x%xn", entry, p->RIOConnectTable[entry].SysPort ) );
  382. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[0].Unit = %bn", entry, p->RIOConnectTable[entry].Topology[0].Unit ) );
  383. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[0].Link = %bn", entry, p->RIOConnectTable[entry].Topology[0].Link ) );
  384. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[1].Unit = %bn", entry, p->RIOConnectTable[entry].Topology[1].Unit ) );
  385. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[1].Link = %bn", entry, p->RIOConnectTable[entry].Topology[1].Link ) );
  386. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[2].Unit = %bn", entry, p->RIOConnectTable[entry].Topology[2].Unit ) );
  387. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[2].Link = %bn", entry, p->RIOConnectTable[entry].Topology[2].Link ) );
  388. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[3].Unit = %bn", entry, p->RIOConnectTable[entry].Topology[3].Unit ) );
  389. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[4].Link = %bn", entry, p->RIOConnectTable[entry].Topology[3].Link ) );
  390. rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Name = %sn", entry, p->RIOConnectTable[entry].Name ) );
  391. }
  392. rio_dprint(RIO_DEBUG_CTRL,  ("*****nEND MAP ENTRIESn") );
  393. }
  394. ***********************************
  395. */
  396. return RIONewTable(p);
  397.   case RIO_GET_BINDINGS :
  398. /*
  399. ** Send bindings table, containing unique numbers of RTAs owned
  400. ** by this system to user space
  401. */
  402. rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGSn");
  403. if ( !su )
  404. {
  405.   rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS !Rootn");
  406.   p->RIOError.Error = NOT_SUPER_USER;
  407.   return EPERM;
  408. }
  409. if (copyout((caddr_t) p->RIOBindTab, (int)arg, 
  410. (sizeof(ulong) * MAX_RTA_BINDINGS)) == COPYFAIL ) {
  411.   rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failedn");
  412.   p->RIOError.Error = COPYOUT_FAILED;
  413.   return EFAULT;
  414. }
  415. return 0;
  416.   case RIO_PUT_BINDINGS :
  417. /*
  418. ** Receive a bindings table, containing unique numbers of RTAs owned
  419. ** by this system
  420. */
  421. rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGSn");
  422. if ( !su )
  423. {
  424.   rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS !Rootn");
  425.   p->RIOError.Error = NOT_SUPER_USER;
  426.   return EPERM;
  427. }
  428. if (copyin((int)arg, (caddr_t)&p->RIOBindTab[0], 
  429. (sizeof(ulong) * MAX_RTA_BINDINGS))==COPYFAIL ) {
  430.   rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failedn");
  431.   p->RIOError.Error = COPYIN_FAILED;
  432.   return EFAULT;
  433. }
  434. return 0;
  435. case RIO_BIND_RTA :
  436. {
  437. int EmptySlot = -1;
  438. /*
  439. ** Bind this RTA to host, so that it will be booted by 
  440. ** host in 'boot owned RTAs' mode.
  441. */
  442. rio_dprintk (RIO_DEBUG_CTRL, "RIO_BIND_RTAn");
  443. if ( !su ) {
  444.   rio_dprintk (RIO_DEBUG_CTRL, "RIO_BIND_RTA !Rootn");
  445.   p->RIOError.Error = NOT_SUPER_USER;
  446.   return EPERM;
  447. }
  448. for (Entry = 0; Entry < MAX_RTA_BINDINGS; Entry++) {
  449.   if ((EmptySlot == -1) && (p->RIOBindTab[Entry] == 0L))
  450. EmptySlot = Entry;
  451.   else if (p->RIOBindTab[Entry] == (int) arg) {
  452. /*
  453. ** Already exists - delete
  454. */
  455. p->RIOBindTab[Entry] = 0L;
  456. rio_dprintk (RIO_DEBUG_CTRL, "Removing Rta %x from p->RIOBindTabn",
  457.   (int) arg);
  458. return 0;
  459.   }
  460. }
  461. /*
  462. ** Dosen't exist - add
  463. */
  464. if (EmptySlot != -1) {
  465.   p->RIOBindTab[EmptySlot] = (int) arg;
  466.   rio_dprintk (RIO_DEBUG_CTRL, "Adding Rta %x to p->RIOBindTabn",
  467.    (int) arg);
  468. }
  469. else {
  470.   rio_dprintk (RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %x not addedn",
  471.    (int) arg);
  472.   return 1;
  473. }
  474. return 0;
  475. }
  476. case RIO_RESUME :
  477. rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUMEn");
  478. port = (uint) arg;
  479. if ((port < 0) || (port > 511)) {
  480.   rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %dn", port);
  481.   p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  482.   return EINVAL;
  483. }
  484. PortP = p->RIOPortp[port];
  485. if (!PortP->Mapped) {
  486.   rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not mappedn", port);
  487.   p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;
  488.   return EINVAL;
  489. }
  490. if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) {
  491. rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not openn", port);
  492.   return EINVAL;
  493. }
  494. rio_spin_lock_irqsave(&PortP->portSem, flags);
  495. if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RESUME) == 
  496. RIO_FAIL) {
  497. rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME failedn");
  498. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  499. return EBUSY;
  500. }
  501. else {
  502. rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d resumedn", port);
  503. PortP->State |= RIO_BUSY;
  504. }
  505. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  506. return retval;
  507. case RIO_ASSIGN_RTA:
  508. rio_dprintk (RIO_DEBUG_CTRL, "RIO_ASSIGN_RTAn");
  509. if ( !su ) {
  510. rio_dprintk (RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA !Rootn");
  511. p->RIOError.Error = NOT_SUPER_USER;
  512. return EPERM;
  513. }
  514. if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
  515. == COPYFAIL) {
  516. rio_dprintk (RIO_DEBUG_CTRL, "Copy from user space failedn");
  517. p->RIOError.Error = COPYIN_FAILED;
  518. return EFAULT;
  519. }
  520. return RIOAssignRta(p, &MapEnt);
  521. case RIO_CHANGE_NAME:
  522. rio_dprintk (RIO_DEBUG_CTRL, "RIO_CHANGE_NAMEn");
  523. if ( !su ) {
  524. rio_dprintk (RIO_DEBUG_CTRL, "RIO_CHANGE_NAME !Rootn");
  525. p->RIOError.Error = NOT_SUPER_USER;
  526. return EPERM;
  527. }
  528. if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
  529. == COPYFAIL) {
  530. rio_dprintk (RIO_DEBUG_CTRL, "Copy from user space failedn");
  531. p->RIOError.Error = COPYIN_FAILED;
  532. return EFAULT;
  533. }
  534. return RIOChangeName(p, &MapEnt);
  535. case RIO_DELETE_RTA:
  536. rio_dprintk (RIO_DEBUG_CTRL, "RIO_DELETE_RTAn");
  537. if ( !su ) {
  538.   rio_dprintk (RIO_DEBUG_CTRL, "RIO_DELETE_RTA !Rootn");
  539.   p->RIOError.Error = NOT_SUPER_USER;
  540.   return EPERM;
  541. }
  542. if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
  543. == COPYFAIL ) {
  544.   rio_dprintk (RIO_DEBUG_CTRL, "Copy from data space failedn");
  545.   p->RIOError.Error = COPYIN_FAILED;
  546.   return EFAULT;
  547. }
  548. return RIODeleteRta(p, &MapEnt);
  549. case RIO_QUICK_CHECK:
  550. /*
  551. ** 09.12.1998 ARG - ESIL 0776 part fix
  552. ** A customer was using this to get the RTAs
  553. ** connect/disconnect status.
  554. ** RIOConCon() had been botched use RIOHalted
  555. ** to keep track of RTA connections and
  556. ** disconnections. That has been changed and
  557. ** RIORtaDisCons in the rio_info struct now
  558. ** does the job. So we need to return the value
  559. ** of RIORtaCons instead of RIOHalted.
  560. **
  561. if (copyout((caddr_t)&p->RIOHalted,(int)arg,
  562. sizeof(uint))==COPYFAIL) {
  563. **
  564. */
  565. if (copyout((caddr_t)&p->RIORtaDisCons,(int)arg,
  566. sizeof(uint))==COPYFAIL) {
  567. p->RIOError.Error = COPYOUT_FAILED;
  568. return EFAULT;
  569. }
  570. return 0;
  571. case RIO_LAST_ERROR:
  572. if (copyout((caddr_t)&p->RIOError, (int)arg, 
  573. sizeof(struct Error)) ==COPYFAIL )
  574. return EFAULT;
  575. return 0;
  576. case RIO_GET_LOG:
  577. rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_LOGn");
  578. #ifdef LOGGING
  579. RIOGetLog(arg);
  580. return 0;
  581. #else
  582. return EINVAL;
  583. #endif
  584. case RIO_GET_MODTYPE:
  585. if ( copyin( (int)arg, (caddr_t)&port, 
  586. sizeof(uint)) == COPYFAIL )
  587. {
  588.   p->RIOError.Error = COPYIN_FAILED;
  589.   return EFAULT;
  590. }
  591. rio_dprintk (RIO_DEBUG_CTRL, "Get module type for port %dn", port);
  592. if ( port < 0 || port > 511 )
  593. {
  594.   rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Bad port number %dn", port);
  595.   p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  596.   return EINVAL;
  597. }
  598. PortP = (p->RIOPortp[port]);
  599. if (!PortP->Mapped)
  600. {
  601.   rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Port %d not mappedn", port);
  602.   p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;
  603.   return EINVAL;
  604. }
  605. /*
  606. ** Return module type of port
  607. */
  608. port = PortP->HostP->UnixRups[PortP->RupNum].ModTypes;
  609. if (copyout((caddr_t)&port, (int)arg, 
  610. sizeof(uint)) == COPYFAIL) {
  611.   p->RIOError.Error = COPYOUT_FAILED;
  612.   return EFAULT;
  613. }
  614. return(0);
  615. /*
  616. ** 02.03.1999 ARG - ESIL 0820 fix
  617. ** We are no longer using "Boot Mode", so these ioctls
  618. ** are not required :
  619. **
  620.   case RIO_GET_BOOT_MODE :
  621. rio_dprint(RIO_DEBUG_CTRL, ("Get boot mode - %xn", p->RIOBootMode));
  622. **
  623. ** Return boot state of system - BOOT_ALL, BOOT_OWN or BOOT_NONE
  624. **
  625. if (copyout((caddr_t)&p->RIOBootMode, (int)arg, 
  626. sizeof(p->RIOBootMode)) == COPYFAIL) {
  627.   p->RIOError.Error = COPYOUT_FAILED;
  628.   return EFAULT;
  629. }
  630. return(0);
  631.   case RIO_SET_BOOT_MODE :
  632. p->RIOBootMode = (uint) arg;
  633. rio_dprint(RIO_DEBUG_CTRL, ("Set boot mode to 0x%xn", p->RIOBootMode));
  634. return(0);
  635. **
  636. ** End ESIL 0820 fix
  637. */
  638.   case RIO_BLOCK_OPENS:
  639. rio_dprintk (RIO_DEBUG_CTRL, "Opens block until bootedn");
  640. for ( Entry=0; Entry < RIO_PORTS; Entry++ ) {
  641.   rio_spin_lock_irqsave(&PortP->portSem, flags);
  642.   p->RIOPortp[Entry]->WaitUntilBooted = 1;
  643.   rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  644. }
  645. return 0;
  646.   case RIO_SETUP_PORTS:
  647. rio_dprintk (RIO_DEBUG_CTRL, "Setup portsn");
  648. if (copyin((int)arg, (caddr_t)&PortSetup, sizeof(PortSetup)) 
  649. == COPYFAIL ) {
  650.  p->RIOError.Error = COPYIN_FAILED;
  651.  rio_dprintk (RIO_DEBUG_CTRL, "EFAULT");
  652.  return EFAULT;
  653. }
  654. if ( PortSetup.From > PortSetup.To || 
  655. PortSetup.To >= RIO_PORTS ) {
  656.  p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  657.  rio_dprintk (RIO_DEBUG_CTRL, "ENXIO");
  658.  return ENXIO;
  659. }
  660. if ( PortSetup.XpCps > p->RIOConf.MaxXpCps ||
  661.  PortSetup.XpCps < p->RIOConf.MinXpCps ) {
  662.  p->RIOError.Error = XPRINT_CPS_OUT_OF_RANGE;
  663.  rio_dprintk (RIO_DEBUG_CTRL, "EINVAL");
  664.  return EINVAL;
  665. }
  666. if ( !p->RIOPortp ) {
  667.  cprintf("No p->RIOPortp array!n");
  668.  rio_dprintk (RIO_DEBUG_CTRL, "No p->RIOPortp array!n");
  669.  return EIO;
  670. }
  671. rio_dprintk (RIO_DEBUG_CTRL, "entering loop (%d %d)!n", PortSetup.From, PortSetup.To);
  672. for (loop=PortSetup.From; loop<=PortSetup.To; loop++) {
  673. rio_dprintk (RIO_DEBUG_CTRL, "in loop (%d)!n", loop);
  674. #if 0
  675. PortP = p->RIOPortp[loop];
  676. if ( !PortP->TtyP )
  677. PortP->TtyP = &p->channel[loop];
  678.   rio_spin_lock_irqsave(&PortP->portSem, flags);
  679. if ( PortSetup.IxAny )
  680. PortP->Config |= RIO_IXANY;
  681. else
  682. PortP->Config &= ~RIO_IXANY;
  683. if ( PortSetup.IxOn )
  684. PortP->Config |= RIO_IXON;
  685. else
  686. PortP->Config &= ~RIO_IXON;
  687.  
  688.  /*
  689.  ** If the port needs to wait for all a processes output
  690.  ** to drain before closing then this flag will be set.
  691.  */
  692.   if (PortSetup.Drain) {
  693. PortP->Config |= RIO_WAITDRAIN;
  694.   } else {
  695. PortP->Config &= ~RIO_WAITDRAIN;
  696.   }
  697.  /*
  698.  ** Store settings if locking or unlocking port or if the
  699.  ** port is not locked, when setting the store option.
  700.  */
  701.  if (PortP->Mapped &&
  702.  ((PortSetup.Lock && !PortP->Lock) ||
  703. (!PortP->Lock &&
  704. (PortSetup.Store && !PortP->Store)))) {
  705. PortP->StoredTty.iflag = PortP->TtyP->tm.c_iflag;
  706. PortP->StoredTty.oflag = PortP->TtyP->tm.c_oflag;
  707. PortP->StoredTty.cflag = PortP->TtyP->tm.c_cflag;
  708. PortP->StoredTty.lflag = PortP->TtyP->tm.c_lflag;
  709. PortP->StoredTty.line = PortP->TtyP->tm.c_line;
  710. bcopy(PortP->TtyP->tm.c_cc, PortP->StoredTty.cc,
  711.   NCC + 5);
  712.  }
  713.  PortP->Lock = PortSetup.Lock;
  714.  PortP->Store = PortSetup.Store;
  715.  PortP->Xprint.XpCps = PortSetup.XpCps;
  716.  bcopy(PortSetup.XpOn,PortP->Xprint.XpOn,MAX_XP_CTRL_LEN);
  717.  bcopy(PortSetup.XpOff,PortP->Xprint.XpOff,MAX_XP_CTRL_LEN);
  718.  PortP->Xprint.XpOn[MAX_XP_CTRL_LEN-1] = '';
  719.  PortP->Xprint.XpOff[MAX_XP_CTRL_LEN-1] = '';
  720.  PortP->Xprint.XpLen = RIOStrlen(PortP->Xprint.XpOn)+
  721. RIOStrlen(PortP->Xprint.XpOff);
  722.  rio_spin_unlock_irqrestore( &PortP->portSem , flags);
  723. #endif
  724. }
  725. rio_dprintk (RIO_DEBUG_CTRL, "after loop (%d)!n", loop);
  726. rio_dprintk (RIO_DEBUG_CTRL, "Retval:%xn", retval);
  727. return retval;
  728. case RIO_GET_PORT_SETUP :
  729. rio_dprintk (RIO_DEBUG_CTRL, "Get port setupn");
  730. if (copyin((int)arg, (caddr_t)&PortSetup, sizeof(PortSetup)) 
  731. == COPYFAIL ) {
  732.  p->RIOError.Error = COPYIN_FAILED;
  733.  return EFAULT;
  734. }
  735. if ( PortSetup.From >= RIO_PORTS ) {
  736.  p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  737.  return ENXIO;
  738. }
  739. port = PortSetup.To = PortSetup.From;
  740. PortSetup.IxAny = (p->RIOPortp[port]->Config & RIO_IXANY) ? 
  741. 1 : 0;
  742. PortSetup.IxOn = (p->RIOPortp[port]->Config & RIO_IXON) ? 
  743. 1 : 0;
  744. PortSetup.Drain = (p->RIOPortp[port]->Config & RIO_WAITDRAIN) ?
  745.   1 : 0;
  746. PortSetup.Store = p->RIOPortp[port]->Store;
  747. PortSetup.Lock = p->RIOPortp[port]->Lock;
  748. PortSetup.XpCps = p->RIOPortp[port]->Xprint.XpCps;
  749. bcopy(p->RIOPortp[port]->Xprint.XpOn, PortSetup.XpOn,
  750. MAX_XP_CTRL_LEN);
  751. bcopy(p->RIOPortp[port]->Xprint.XpOff, PortSetup.XpOff,
  752. MAX_XP_CTRL_LEN);
  753. PortSetup.XpOn[MAX_XP_CTRL_LEN-1] = '';
  754. PortSetup.XpOff[MAX_XP_CTRL_LEN-1] = '';
  755. if ( copyout((caddr_t)&PortSetup,(int)arg,sizeof(PortSetup))
  756. ==COPYFAIL ) {
  757.  p->RIOError.Error = COPYOUT_FAILED;
  758.  return EFAULT;
  759. }
  760. return retval;
  761. case RIO_GET_PORT_PARAMS :
  762. rio_dprintk (RIO_DEBUG_CTRL, "Get port paramsn");
  763. if (copyin( (int)arg, (caddr_t)&PortParams,
  764. sizeof(struct PortParams)) == COPYFAIL) {
  765. p->RIOError.Error = COPYIN_FAILED;
  766. return EFAULT;
  767. }
  768. if (PortParams.Port >= RIO_PORTS) {
  769. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  770. return ENXIO;
  771. }
  772. PortP = (p->RIOPortp[PortParams.Port]);
  773. PortParams.Config = PortP->Config;
  774. PortParams.State = PortP->State;
  775. rio_dprintk (RIO_DEBUG_CTRL, "Port %dn", PortParams.Port);
  776. if (copyout((caddr_t)&PortParams, (int)arg, 
  777. sizeof(struct PortParams)) == COPYFAIL ) {
  778.  p->RIOError.Error = COPYOUT_FAILED;
  779.  return EFAULT;
  780. }
  781. return retval;
  782. case RIO_GET_PORT_TTY :
  783. rio_dprintk (RIO_DEBUG_CTRL, "Get port ttyn");
  784. if (copyin((int)arg, (caddr_t)&PortTty, sizeof(struct PortTty)) 
  785. == COPYFAIL) {
  786.  p->RIOError.Error = COPYIN_FAILED;
  787.  return EFAULT;
  788. }
  789. if ( PortTty.port >= RIO_PORTS ) {
  790.  p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  791.  return ENXIO;
  792. }
  793. rio_dprintk (RIO_DEBUG_CTRL, "Port %dn", PortTty.port);
  794. PortP = (p->RIOPortp[PortTty.port]);
  795. #if 0
  796. PortTty.Tty.tm.c_iflag = PortP->TtyP->tm.c_iflag;
  797. PortTty.Tty.tm.c_oflag = PortP->TtyP->tm.c_oflag;
  798. PortTty.Tty.tm.c_cflag = PortP->TtyP->tm.c_cflag;
  799. PortTty.Tty.tm.c_lflag = PortP->TtyP->tm.c_lflag;
  800. #endif
  801. if (copyout((caddr_t)&PortTty, (int)arg, 
  802. sizeof(struct PortTty)) == COPYFAIL) {
  803. p->RIOError.Error = COPYOUT_FAILED;
  804. return EFAULT;
  805. }
  806. return retval;
  807. case RIO_SET_PORT_TTY :
  808. if (copyin((int)arg, (caddr_t)&PortTty, 
  809. sizeof(struct PortTty)) == COPYFAIL) {
  810.  p->RIOError.Error = COPYIN_FAILED;
  811.  return EFAULT;
  812. }
  813. rio_dprintk (RIO_DEBUG_CTRL, "Set port %d ttyn", PortTty.port);
  814. if (PortTty.port >= (ushort) RIO_PORTS) {
  815.  p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  816.  return ENXIO;
  817. }
  818. PortP = (p->RIOPortp[PortTty.port]);
  819. #if 0
  820.   rio_spin_lock_irqsave(&PortP->portSem, flags);
  821. PortP->TtyP->tm.c_iflag = PortTty.Tty.tm.c_iflag;
  822. PortP->TtyP->tm.c_oflag = PortTty.Tty.tm.c_oflag;
  823. PortP->TtyP->tm.c_cflag = PortTty.Tty.tm.c_cflag;
  824. PortP->TtyP->tm.c_lflag = PortTty.Tty.tm.c_lflag;
  825. rio_spin_unlock_irqrestore( &PortP->portSem , flags);
  826. #endif
  827. RIOParam(PortP, CONFIG, PortP->State & RIO_MODEM, OK_TO_SLEEP);
  828. return retval;
  829. case RIO_SET_PORT_PARAMS :
  830. rio_dprintk (RIO_DEBUG_CTRL, "Set port paramsn");
  831. if ( copyin((int)arg, (caddr_t)&PortParams, sizeof(PortParams))
  832. == COPYFAIL ) {
  833.  p->RIOError.Error = COPYIN_FAILED;
  834.  return EFAULT;
  835. }
  836. if (PortParams.Port >= (ushort) RIO_PORTS) {
  837.  p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  838.  return ENXIO;
  839. }
  840. PortP = (p->RIOPortp[PortParams.Port]);
  841.   rio_spin_lock_irqsave(&PortP->portSem, flags);
  842. PortP->Config = PortParams.Config;
  843. rio_spin_unlock_irqrestore( &PortP->portSem , flags);
  844. return retval;
  845. case RIO_GET_PORT_STATS :
  846. rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_PORT_STATSn");
  847. if ( copyin((int)arg, (caddr_t)&portStats, 
  848. sizeof(struct portStats)) == COPYFAIL ) {
  849.  p->RIOError.Error = COPYIN_FAILED;
  850.  return EFAULT;
  851. }
  852. if ( portStats.port >= RIO_PORTS ) {
  853.  p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  854.  return ENXIO;
  855. }
  856. PortP = (p->RIOPortp[portStats.port]);
  857. portStats.gather = PortP->statsGather;
  858. portStats.txchars = PortP->txchars;
  859. portStats.rxchars = PortP->rxchars;
  860. portStats.opens = PortP->opens;
  861. portStats.closes = PortP->closes;
  862. portStats.ioctls = PortP->ioctls;
  863. if ( copyout((caddr_t)&portStats, (int)arg, 
  864. sizeof(struct portStats)) == COPYFAIL ) {
  865.  p->RIOError.Error = COPYOUT_FAILED;
  866.  return EFAULT;
  867. }
  868. return retval;
  869. case RIO_RESET_PORT_STATS :
  870. port = (uint) arg;
  871. rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATSn");
  872. if ( port >= RIO_PORTS ) {
  873.  p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  874.  return ENXIO;
  875. }
  876. PortP = (p->RIOPortp[port]);
  877. rio_spin_lock_irqsave(&PortP->portSem, flags);
  878. PortP->txchars = 0;
  879. PortP->rxchars = 0;
  880. PortP->opens = 0;
  881. PortP->closes = 0;
  882. PortP->ioctls = 0;
  883. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  884. return retval;
  885. case RIO_GATHER_PORT_STATS :
  886. rio_dprintk (RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATSn");
  887. if ( copyin( (int)arg, (caddr_t)&portStats, 
  888. sizeof(struct portStats)) == COPYFAIL ) {
  889.  p->RIOError.Error = COPYIN_FAILED;
  890.  return EFAULT;
  891. }
  892. if ( portStats.port >= RIO_PORTS ) {
  893.  p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  894.  return ENXIO;
  895. }
  896. PortP = (p->RIOPortp[portStats.port]);
  897. rio_spin_lock_irqsave(&PortP->portSem, flags);
  898. PortP->statsGather = portStats.gather;
  899. rio_spin_unlock_irqrestore( &PortP->portSem , flags);
  900. return retval;
  901. #ifdef DEBUG_SUPPORTED
  902. case RIO_READ_LEVELS:
  903. {
  904.  int num;
  905.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_LEVELSn");
  906.  for ( num=0; RIODbInf[num].Flag; num++ ) ;
  907.  rio_dprintk (RIO_DEBUG_CTRL, "%d levels to copyn",num);
  908.  if (copyout((caddr_t)RIODbInf,(int)arg,
  909. sizeof(struct DbInf)*(num+1))==COPYFAIL) {
  910. rio_dprintk (RIO_DEBUG_CTRL, "ReadLevels Copy failedn");
  911. p->RIOError.Error = COPYOUT_FAILED;
  912. return EFAULT;
  913.  }
  914.  rio_dprintk (RIO_DEBUG_CTRL, "%d levels to copiedn",num);
  915.  return retval;
  916. }
  917. #endif
  918.  case RIO_READ_CONFIG:
  919. rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_CONFIGn");
  920. if (copyout((caddr_t)&p->RIOConf, (int)arg, 
  921. sizeof(struct Conf)) ==COPYFAIL ) {
  922.  p->RIOError.Error = COPYOUT_FAILED;
  923.  return EFAULT;
  924. }
  925. return retval;
  926. case RIO_SET_CONFIG:
  927. rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_CONFIGn");
  928. if ( !su ) {
  929.  p->RIOError.Error = NOT_SUPER_USER;
  930.  return EPERM;
  931. }
  932. if ( copyin((int)arg, (caddr_t)&p->RIOConf, sizeof(struct Conf) )
  933. ==COPYFAIL ) {
  934.  p->RIOError.Error = COPYIN_FAILED;
  935.  return EFAULT;
  936. }
  937. /*
  938. ** move a few value around
  939. */
  940. for (Host=0; Host < p->RIONumHosts; Host++)
  941.  if ( (p->RIOHosts[Host].Flags & RUN_STATE) == RC_RUNNING )
  942.   WWORD(p->RIOHosts[Host].ParmMapP->timer , 
  943. p->RIOConf.Timer);
  944. return retval;
  945. case RIO_START_POLLER:
  946. rio_dprintk (RIO_DEBUG_CTRL, "RIO_START_POLLERn");
  947. return EINVAL;
  948. case RIO_STOP_POLLER:
  949. rio_dprintk (RIO_DEBUG_CTRL, "RIO_STOP_POLLERn");
  950. if ( !su ) {
  951.  p->RIOError.Error = NOT_SUPER_USER;
  952.  return EPERM;
  953. }
  954. p->RIOPolling = NOT_POLLING;
  955. return retval;
  956. case RIO_SETDEBUG:
  957. case RIO_GETDEBUG:
  958. rio_dprintk (RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUGn");
  959. if ( copyin( (int)arg, (caddr_t)&DebugCtrl, sizeof(DebugCtrl) )
  960. ==COPYFAIL ) {
  961.  p->RIOError.Error = COPYIN_FAILED;
  962.  return EFAULT;
  963. }
  964. if ( DebugCtrl.SysPort == NO_PORT ) {
  965. if ( cmd == RIO_SETDEBUG ) {
  966. if ( !su ) {
  967. p->RIOError.Error = NOT_SUPER_USER;
  968. return EPERM;
  969. }
  970. p->rio_debug = DebugCtrl.Debug;
  971. p->RIODebugWait = DebugCtrl.Wait;
  972. rio_dprintk (RIO_DEBUG_CTRL, "Set global debug to 0x%x set wait to 0x%xn",
  973. p->rio_debug,p->RIODebugWait);
  974. }
  975.   else {
  976. rio_dprintk (RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%xn",
  977. p->rio_debug,p->RIODebugWait);
  978. DebugCtrl.Debug = p->rio_debug;
  979. DebugCtrl.Wait  = p->RIODebugWait;
  980. if ( copyout((caddr_t)&DebugCtrl,(int)arg,
  981. sizeof(DebugCtrl)) == COPYFAIL ) {
  982. rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %dn",
  983. DebugCtrl.SysPort);
  984.   p->RIOError.Error = COPYOUT_FAILED;
  985.   return EFAULT;
  986. }
  987. }
  988. }
  989. else if ( DebugCtrl.SysPort >= RIO_PORTS && 
  990. DebugCtrl.SysPort != NO_PORT ) {
  991.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %dn",
  992. DebugCtrl.SysPort);
  993.  p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  994.  return ENXIO;
  995. }
  996. else if ( cmd == RIO_SETDEBUG ) {
  997. if ( !su ) {
  998. p->RIOError.Error = NOT_SUPER_USER;
  999. return EPERM;
  1000. }
  1001. rio_spin_lock_irqsave(&PortP->portSem, flags);
  1002. p->RIOPortp[DebugCtrl.SysPort]->Debug = DebugCtrl.Debug;
  1003. rio_spin_unlock_irqrestore( &PortP->portSem , flags);
  1004. rio_dprintk (RIO_DEBUG_CTRL, "RIO_SETDEBUG 0x%xn",
  1005. p->RIOPortp[DebugCtrl.SysPort]->Debug);
  1006. }
  1007. else {
  1008. rio_dprintk (RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%xn",
  1009.  p->RIOPortp[DebugCtrl.SysPort]->Debug);
  1010. DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug;
  1011. if ( copyout((caddr_t)&DebugCtrl,(int)arg,
  1012. sizeof(DebugCtrl))==COPYFAIL ) {
  1013. rio_dprintk (RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user spacen");
  1014. p->RIOError.Error = COPYOUT_FAILED;
  1015. return EFAULT;
  1016. }
  1017. }
  1018. return retval;
  1019. case RIO_VERSID:
  1020. /*
  1021. ** Enquire about the release and version.
  1022. ** We return MAX_VERSION_LEN bytes, being a
  1023. ** textual null terminated string.
  1024. */
  1025. rio_dprintk (RIO_DEBUG_CTRL, "RIO_VERSIDn");
  1026. if ( copyout( (caddr_t)RIOVersid(),
  1027. (int)arg,
  1028. sizeof(struct rioVersion) ) == COPYFAIL )
  1029. {
  1030.  rio_dprintk (RIO_DEBUG_CTRL,  "RIO_VERSID: Bad copy to user space (host=%d)n", Host);
  1031.  p->RIOError.Error = COPYOUT_FAILED;
  1032.  return EFAULT;
  1033. }
  1034. return retval;
  1035. /*
  1036. ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1037. ** !! commented out previous 'RIO_VERSID' functionality !!
  1038. ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1039. **
  1040. case RIO_VERSID:
  1041. **
  1042. ** Enquire about the release and version.
  1043. ** We return MAX_VERSION_LEN bytes, being a textual null
  1044. ** terminated string.
  1045. **
  1046. rio_dprint(RIO_DEBUG_CTRL, ("RIO_VERSIDn"));
  1047. if (copyout((caddr_t)RIOVersid(), 
  1048. (int)arg, MAX_VERSION_LEN ) == COPYFAIL ) {
  1049.  rio_dprint(RIO_DEBUG_CTRL, ("RIO_VERSID: Bad copy to user spacen",Host));
  1050.  p->RIOError.Error = COPYOUT_FAILED;
  1051.  return EFAULT;
  1052. }
  1053. return retval;
  1054. **
  1055. ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1056. */
  1057. case RIO_NUM_HOSTS:
  1058. /*
  1059. ** Enquire as to the number of hosts located
  1060. ** at init time.
  1061. */
  1062. rio_dprintk (RIO_DEBUG_CTRL, "RIO_NUM_HOSTSn");
  1063. if (copyout((caddr_t)&p->RIONumHosts, (int)arg, 
  1064. sizeof(p->RIONumHosts) )==COPYFAIL ) {
  1065.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user spacen");
  1066.  p->RIOError.Error = COPYOUT_FAILED;
  1067.  return EFAULT;
  1068. }
  1069. return retval;
  1070. case RIO_HOST_FOAD:
  1071. /*
  1072. ** Kill host. This may not be in the final version...
  1073. */
  1074. rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_FOAD %dn", (int)arg);
  1075. if ( !su ) {
  1076.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super usern");
  1077.  p->RIOError.Error = NOT_SUPER_USER;
  1078.  return EPERM;
  1079. }
  1080. p->RIOHalted = 1;
  1081. p->RIOSystemUp = 0;
  1082. for ( Host=0; Host<p->RIONumHosts; Host++ ) {
  1083.  (void)RIOBoardTest( p->RIOHosts[Host].PaddrP, 
  1084. p->RIOHosts[Host].Caddr, p->RIOHosts[Host].Type, 
  1085. p->RIOHosts[Host].Slot );
  1086.  bzero( (caddr_t)&p->RIOHosts[Host].Flags, 
  1087. ((int)&p->RIOHosts[Host].____end_marker____) -
  1088.  ((int)&p->RIOHosts[Host].Flags) );
  1089.  p->RIOHosts[Host].Flags  = RC_WAITING;
  1090. #if 0
  1091.  RIOSetupDataStructs(p);
  1092. #endif
  1093. }
  1094. RIOFoadWakeup(p);
  1095. p->RIONumBootPkts = 0;
  1096. p->RIOBooting = 0;
  1097. #ifdef RINGBUFFER_SUPPORT
  1098. for( loop=0; loop<RIO_PORTS; loop++ )
  1099. if ( p->RIOPortp[loop]->TxRingBuffer )
  1100. sysfree((void *)p->RIOPortp[loop]->TxRingBuffer, 
  1101. RIOBufferSize );
  1102. #endif
  1103. #if 0
  1104. bzero((caddr_t)&p->RIOPortp[0],RIO_PORTS*sizeof(struct Port));
  1105. #else
  1106. printk ("HEEEEELP!n");
  1107. #endif
  1108. for( loop=0; loop<RIO_PORTS; loop++ ) {
  1109. #if 0
  1110. p->RIOPortp[loop]->TtyP = &p->channel[loop];
  1111. #endif
  1112. p->RIOPortp[loop]->portSem = SPIN_LOCK_UNLOCKED;
  1113. p->RIOPortp[loop]->InUse = NOT_INUSE;
  1114. }
  1115. p->RIOSystemUp = 0;
  1116. return retval;
  1117. case RIO_DOWNLOAD:
  1118. rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOADn");
  1119. if ( !su ) {
  1120.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Not super usern");
  1121.  p->RIOError.Error = NOT_SUPER_USER;
  1122.  return EPERM;
  1123. }
  1124. if ( copyin((int)arg, (caddr_t)&DownLoad, 
  1125. sizeof(DownLoad) )==COPYFAIL ) {
  1126.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failedn");
  1127.  p->RIOError.Error = COPYIN_FAILED;
  1128.  return EFAULT;
  1129. }
  1130. rio_dprintk (RIO_DEBUG_CTRL, "Copied in download code for product code 0x%xn",
  1131.     DownLoad.ProductCode);
  1132. /*
  1133. ** It is important that the product code is an unsigned object!
  1134. */
  1135. if ( DownLoad.ProductCode > MAX_PRODUCT ) {
  1136.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passedn",
  1137. DownLoad.ProductCode);
  1138.  p->RIOError.Error = NO_SUCH_PRODUCT;
  1139.  return ENXIO;
  1140. }
  1141. /*
  1142. ** do something!
  1143. */
  1144. retval = (*(RIOBootTable[DownLoad.ProductCode]))(p, &DownLoad);
  1145. /* <-- Panic */
  1146. p->RIOHalted = 0;
  1147. /*
  1148. ** and go back, content with a job well completed.
  1149. */
  1150. return retval;
  1151. case RIO_PARMS:
  1152. {
  1153. uint host;
  1154. if (copyin((int)arg, (caddr_t)&host, 
  1155. sizeof(host) ) == COPYFAIL ) {
  1156. rio_dprintk (RIO_DEBUG_CTRL, 
  1157. "RIO_HOST_REQ: Copy in from user space failedn");
  1158. p->RIOError.Error = COPYIN_FAILED;
  1159. return EFAULT;
  1160. }
  1161. /*
  1162. ** Fetch the parmmap
  1163. */
  1164. rio_dprintk (RIO_DEBUG_CTRL, "RIO_PARMSn");
  1165. if ( copyout( (caddr_t)p->RIOHosts[host].ParmMapP, 
  1166. (int)arg, sizeof(PARM_MAP) )==COPYFAIL ) {
  1167. p->RIOError.Error = COPYOUT_FAILED;
  1168. rio_dprintk (RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failedn");
  1169. return EFAULT;
  1170. }
  1171. }
  1172. return retval;
  1173. case RIO_HOST_REQ:
  1174. rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQn");
  1175. if (copyin((int)arg, (caddr_t)&HostReq, 
  1176. sizeof(HostReq) )==COPYFAIL ) {
  1177.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failedn");
  1178.  p->RIOError.Error = COPYIN_FAILED;
  1179.  return EFAULT;
  1180. }
  1181. if ( HostReq.HostNum >= p->RIONumHosts ) {
  1182.  p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
  1183.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Illegal host number %dn",
  1184. HostReq.HostNum);
  1185.  return ENXIO;
  1186. }
  1187. rio_dprintk (RIO_DEBUG_CTRL, "Request for host %dn", HostReq.HostNum);
  1188. if (copyout((caddr_t)&p->RIOHosts[HostReq.HostNum], 
  1189. (int)HostReq.HostP,sizeof(struct Host) ) == COPYFAIL) {
  1190. p->RIOError.Error = COPYOUT_FAILED;
  1191. rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Bad copy to user spacen");
  1192. return EFAULT;
  1193. }
  1194. return retval;
  1195.  case RIO_HOST_DPRAM:
  1196. rio_dprintk (RIO_DEBUG_CTRL, "Request for DPRAMn");
  1197. if ( copyin( (int)arg, (caddr_t)&HostDpRam, 
  1198. sizeof(HostDpRam) )==COPYFAIL ) {
  1199. rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failedn");
  1200. p->RIOError.Error = COPYIN_FAILED;
  1201. return EFAULT;
  1202. }
  1203. if ( HostDpRam.HostNum >= p->RIONumHosts ) {
  1204. p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
  1205. rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Illegal host number %dn",
  1206. HostDpRam.HostNum);
  1207. return ENXIO;
  1208. }
  1209. rio_dprintk (RIO_DEBUG_CTRL, "Request for host %dn", HostDpRam.HostNum);
  1210. if (p->RIOHosts[HostDpRam.HostNum].Type == RIO_PCI) {
  1211.  int off;
  1212.  /* It's hardware like this that really gets on my tits. */
  1213.  static unsigned char copy[sizeof(struct DpRam)];
  1214. for ( off=0; off<sizeof(struct DpRam); off++ )
  1215. copy[off] = p->RIOHosts[HostDpRam.HostNum].Caddr[off];
  1216. if ( copyout( (caddr_t)copy, (int)HostDpRam.DpRamP, 
  1217. sizeof(struct DpRam) ) == COPYFAIL ) {
  1218. p->RIOError.Error = COPYOUT_FAILED;
  1219. rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user spacen");
  1220. return EFAULT;
  1221. }
  1222. }
  1223. else if (copyout((caddr_t)p->RIOHosts[HostDpRam.HostNum].Caddr,
  1224. (int)HostDpRam.DpRamP, 
  1225. sizeof(struct DpRam) ) == COPYFAIL ) {
  1226.  p->RIOError.Error = COPYOUT_FAILED;
  1227.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user spacen");
  1228.  return EFAULT;
  1229. }
  1230. return retval;
  1231.  case RIO_SET_BUSY:
  1232. rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_BUSYn");
  1233. if ( (int)arg < 0 || (int)arg > 511 ) {
  1234.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %dn",(int)arg);
  1235.  p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  1236.  return EINVAL;
  1237. }
  1238. rio_spin_lock_irqsave(&PortP->portSem, flags);
  1239. p->RIOPortp[(int)arg]->State |= RIO_BUSY;
  1240. rio_spin_unlock_irqrestore( &PortP->portSem , flags);
  1241. return retval;
  1242.  case RIO_HOST_PORT:
  1243. /*
  1244. ** The daemon want port information
  1245. ** (probably for debug reasons)
  1246. */
  1247. rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORTn");
  1248. if ( copyin((int)arg, (caddr_t)&PortReq, 
  1249. sizeof(PortReq) )==COPYFAIL ) {
  1250. rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failedn");
  1251. p->RIOError.Error = COPYIN_FAILED;
  1252. return EFAULT;
  1253. }
  1254. if (PortReq.SysPort >= RIO_PORTS) { /* SysPort is unsigned */
  1255.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Illegal port number %dn",
  1256. PortReq.SysPort);
  1257.  p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  1258.  return ENXIO;
  1259. }
  1260. rio_dprintk (RIO_DEBUG_CTRL, "Request for port %dn", PortReq.SysPort);
  1261. if (copyout((caddr_t)p->RIOPortp[PortReq.SysPort], 
  1262.  (int)PortReq.PortP,
  1263. sizeof(struct Port) ) == COPYFAIL) {
  1264.  p->RIOError.Error = COPYOUT_FAILED;
  1265.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Bad copy to user spacen");
  1266.  return EFAULT;
  1267. }
  1268. return retval;
  1269. case RIO_HOST_RUP:
  1270. /*
  1271. ** The daemon want rup information
  1272. ** (probably for debug reasons)
  1273. */
  1274. rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUPn");
  1275. if (copyin((int)arg, (caddr_t)&RupReq, 
  1276. sizeof(RupReq) )==COPYFAIL ) {
  1277.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failedn");
  1278.  p->RIOError.Error = COPYIN_FAILED;
  1279.  return EFAULT;
  1280. }
  1281. if (RupReq.HostNum >= p->RIONumHosts) { /* host is unsigned */
  1282.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal host number %dn",
  1283. RupReq.HostNum);
  1284.  p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
  1285.  return ENXIO;
  1286. }
  1287. if ( RupReq.RupNum >= MAX_RUP+LINKS_PER_UNIT ) { /* eek! */
  1288.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal rup number %dn",
  1289. RupReq.RupNum);
  1290.  p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
  1291.  return EINVAL;
  1292. }
  1293. HostP = &p->RIOHosts[RupReq.HostNum];
  1294. if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
  1295.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Host %d not runningn",
  1296. RupReq.HostNum);
  1297.  p->RIOError.Error = HOST_NOT_RUNNING;
  1298.  return EIO;
  1299. }
  1300. rio_dprintk (RIO_DEBUG_CTRL, "Request for rup %d from host %dn",
  1301. RupReq.RupNum,RupReq.HostNum);
  1302. if (copyout((caddr_t)HostP->UnixRups[RupReq.RupNum].RupP,
  1303. (int)RupReq.RupP,sizeof(struct RUP) ) == COPYFAIL) {
  1304. p->RIOError.Error = COPYOUT_FAILED;
  1305. rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user spacen");
  1306. return EFAULT;
  1307. }
  1308. return retval;
  1309. case RIO_HOST_LPB:
  1310. /*
  1311. ** The daemon want lpb information
  1312. ** (probably for debug reasons)
  1313. */
  1314. rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPBn");
  1315. if (copyin((int)arg, (caddr_t)&LpbReq, 
  1316. sizeof(LpbReq) )==COPYFAIL ) {
  1317.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user spacen");
  1318.  p->RIOError.Error = COPYIN_FAILED;
  1319.  return EFAULT;
  1320. }
  1321. if (LpbReq.Host >= p->RIONumHosts) { /* host is unsigned */
  1322. rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal host number %dn",
  1323. LpbReq.Host);
  1324. p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
  1325. return ENXIO;
  1326. }
  1327. if ( LpbReq.Link >= LINKS_PER_UNIT ) { /* eek! */
  1328.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %dn",
  1329. LpbReq.Link);
  1330.  p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE;
  1331.  return EINVAL;
  1332. }
  1333. HostP = &p->RIOHosts[LpbReq.Host];
  1334. if ( (HostP->Flags & RUN_STATE) != RC_RUNNING ) {
  1335.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not runningn",
  1336. LpbReq.Host );
  1337.  p->RIOError.Error = HOST_NOT_RUNNING;
  1338.  return EIO;
  1339. }
  1340. rio_dprintk (RIO_DEBUG_CTRL, "Request for lpb %d from host %dn",
  1341. LpbReq.Link, LpbReq.Host);
  1342. if (copyout((caddr_t)&HostP->LinkStrP[LpbReq.Link],
  1343. (int)LpbReq.LpbP,sizeof(struct LPB) ) == COPYFAIL) {
  1344. rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user spacen");
  1345. p->RIOError.Error = COPYOUT_FAILED;
  1346. return EFAULT;
  1347. }
  1348. return retval;
  1349. /*
  1350. ** Here 3 IOCTL's that allow us to change the way in which
  1351. ** rio logs errors. send them just to syslog or send them
  1352. ** to both syslog and console or send them to just the console.
  1353. **
  1354. ** See RioStrBuf() in util.c for the other half.
  1355. */
  1356. case RIO_SYSLOG_ONLY:
  1357. p->RIOPrintLogState = PRINT_TO_LOG; /* Just syslog */
  1358. return 0;
  1359. case RIO_SYSLOG_CONS:
  1360. p->RIOPrintLogState = PRINT_TO_LOG_CONS;/* syslog and console */
  1361. return 0;
  1362. case RIO_CONS_ONLY:
  1363. p->RIOPrintLogState = PRINT_TO_CONS; /* Just console */
  1364. return 0;
  1365. case RIO_SIGNALS_ON:
  1366. if ( p->RIOSignalProcess ) {
  1367.  p->RIOError.Error = SIGNALS_ALREADY_SET;
  1368.  return EBUSY;
  1369. }
  1370. p->RIOSignalProcess = getpid();
  1371. p->RIOPrintDisabled = DONT_PRINT;
  1372. return retval;
  1373. case RIO_SIGNALS_OFF:
  1374. if ( p->RIOSignalProcess != getpid() ) {
  1375.  p->RIOError.Error = NOT_RECEIVING_PROCESS;
  1376.  return EPERM;
  1377. }
  1378. rio_dprintk (RIO_DEBUG_CTRL, "Clear signal process to zeron");
  1379. p->RIOSignalProcess = 0;
  1380. return retval;
  1381. case RIO_SET_BYTE_MODE:
  1382. for ( Host=0; Host<p->RIONumHosts; Host++ )
  1383.  if ( p->RIOHosts[Host].Type == RIO_AT )
  1384.  p->RIOHosts[Host].Mode &= ~WORD_OPERATION;
  1385. return retval;
  1386. case RIO_SET_WORD_MODE:
  1387. for ( Host=0; Host<p->RIONumHosts; Host++ )
  1388.  if ( p->RIOHosts[Host].Type == RIO_AT )
  1389.  p->RIOHosts[Host].Mode |= WORD_OPERATION;
  1390. return retval;
  1391. case RIO_SET_FAST_BUS:
  1392. for ( Host=0; Host<p->RIONumHosts; Host++ )
  1393.  if ( p->RIOHosts[Host].Type == RIO_AT )
  1394.  p->RIOHosts[Host].Mode |= FAST_AT_BUS;
  1395. return retval;
  1396. case RIO_SET_SLOW_BUS:
  1397. for ( Host=0; Host<p->RIONumHosts; Host++ )
  1398.  if ( p->RIOHosts[Host].Type == RIO_AT )
  1399.  p->RIOHosts[Host].Mode &= ~FAST_AT_BUS;
  1400. return retval;
  1401. case RIO_MAP_B50_TO_50:
  1402. case RIO_MAP_B50_TO_57600:
  1403. case RIO_MAP_B110_TO_110:
  1404. case RIO_MAP_B110_TO_115200:
  1405. rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mappingn");
  1406. port = (uint) arg;
  1407. if ( port < 0 || port > 511 ) {
  1408.  rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %dn", port);
  1409.  p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  1410.  return EINVAL;
  1411. }
  1412. rio_spin_lock_irqsave(&PortP->portSem, flags);
  1413. switch( cmd )
  1414. {
  1415. case RIO_MAP_B50_TO_50 :
  1416. p->RIOPortp[port]->Config |= RIO_MAP_50_TO_50;
  1417. break;
  1418. case RIO_MAP_B50_TO_57600 :
  1419. p->RIOPortp[port]->Config &= ~RIO_MAP_50_TO_50;
  1420. break;
  1421. case RIO_MAP_B110_TO_110 :
  1422. p->RIOPortp[port]->Config |= RIO_MAP_110_TO_110;
  1423. break;
  1424. case RIO_MAP_B110_TO_115200 :
  1425. p->RIOPortp[port]->Config &= ~RIO_MAP_110_TO_110;
  1426. break;
  1427. }
  1428. rio_spin_unlock_irqrestore( &PortP->portSem , flags);
  1429. return retval;
  1430. case RIO_STREAM_INFO:
  1431. rio_dprintk (RIO_DEBUG_CTRL, "RIO_STREAM_INFOn");
  1432. return EINVAL;
  1433. case RIO_SEND_PACKET:
  1434. rio_dprintk (RIO_DEBUG_CTRL, "RIO_SEND_PACKETn");
  1435. if ( copyin( (int)arg, (caddr_t)&SendPack,
  1436. sizeof(SendPack) )==COPYFAIL ) {
  1437.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user spacen");
  1438.  p->RIOError.Error = COPYIN_FAILED;
  1439.  return EFAULT;
  1440. }
  1441. if ( SendPack.PortNum >= 128 ) {
  1442.  p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  1443.  return ENXIO;
  1444. }
  1445. PortP = p->RIOPortp[SendPack.PortNum];
  1446. rio_spin_lock_irqsave(&PortP->portSem, flags);
  1447. if ( !can_add_transmit(&PacketP,PortP) ) {
  1448.  p->RIOError.Error = UNIT_IS_IN_USE;
  1449.  rio_spin_unlock_irqrestore( &PortP->portSem , flags);
  1450.  return ENOSPC;
  1451. }
  1452. for ( loop=0; loop<(ushort)(SendPack.Len & 127); loop++ )
  1453.  WBYTE(PacketP->data[loop], SendPack.Data[loop] );
  1454. WBYTE(PacketP->len, SendPack.Len);
  1455. add_transmit( PortP );
  1456. /*
  1457. ** Count characters transmitted for port statistics reporting
  1458. */
  1459. if (PortP->statsGather)
  1460.  PortP->txchars += (SendPack.Len & 127);
  1461. rio_spin_unlock_irqrestore( &PortP->portSem , flags);
  1462. return retval;
  1463. case RIO_NO_MESG:
  1464. if ( su )
  1465.  p->RIONoMessage = 1;
  1466. return su ? 0 : EPERM;
  1467. case RIO_MESG:
  1468. if ( su )
  1469. p->RIONoMessage = 0;
  1470. return su ? 0 : EPERM;
  1471. case RIO_WHAT_MESG:
  1472. if ( copyout( (caddr_t)&p->RIONoMessage, (int)arg, 
  1473. sizeof(p->RIONoMessage) )==COPYFAIL ) {
  1474. rio_dprintk (RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user spacen");
  1475. p->RIOError.Error = COPYOUT_FAILED;
  1476. return EFAULT;
  1477. }
  1478. return 0;
  1479. case RIO_MEM_DUMP :
  1480. if (copyin((int)arg, (caddr_t)&SubCmd, 
  1481. sizeof(struct SubCmdStruct)) == COPYFAIL) {
  1482.  p->RIOError.Error = COPYIN_FAILED;
  1483.  return EFAULT;
  1484. }
  1485. rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP host %d rup %d addr %xn", 
  1486. SubCmd.Host, SubCmd.Rup, SubCmd.Addr);
  1487. if (SubCmd.Rup >= MAX_RUP+LINKS_PER_UNIT ) {
  1488.  p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
  1489.  return EINVAL;
  1490. }
  1491. if (SubCmd.Host >= p->RIONumHosts ) {
  1492.  p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
  1493.  return EINVAL;
  1494. }
  1495. port = p->RIOHosts[SubCmd.Host].
  1496. UnixRups[SubCmd.Rup].BaseSysPort;
  1497. PortP = p->RIOPortp[port];
  1498. rio_spin_lock_irqsave(&PortP->portSem, flags);
  1499. if ( RIOPreemptiveCmd(p,  PortP, MEMDUMP ) == RIO_FAIL ) {
  1500.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP failedn");
  1501.  rio_spin_unlock_irqrestore( &PortP->portSem , flags);
  1502.  return EBUSY;
  1503. }
  1504. else
  1505.  PortP->State |= RIO_BUSY;
  1506. rio_spin_unlock_irqrestore( &PortP->portSem , flags);
  1507. if ( copyout( (caddr_t)p->RIOMemDump, (int)arg, 
  1508. MEMDUMP_SIZE) == COPYFAIL ) {
  1509.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failedn");
  1510.  p->RIOError.Error = COPYOUT_FAILED;
  1511.  return EFAULT;
  1512. }
  1513. return 0;
  1514. case RIO_TICK:
  1515. if ((int)arg < 0 || (int)arg >= p->RIONumHosts)
  1516.  return EINVAL;
  1517. rio_dprintk (RIO_DEBUG_CTRL, "Set interrupt for host %dn", (int)arg);
  1518. WBYTE(p->RIOHosts[(int)arg].SetInt , 0xff);
  1519. return 0;
  1520. case RIO_TOCK:
  1521. if ((int)arg < 0 || (int)arg >= p->RIONumHosts)
  1522.  return EINVAL;
  1523. rio_dprintk (RIO_DEBUG_CTRL, "Clear interrupt for host %dn", (int)arg);
  1524. WBYTE((p->RIOHosts[(int)arg].ResetInt) , 0xff);
  1525. return 0;
  1526. case RIO_READ_CHECK:
  1527. /* Check reads for pkts with data[0] the same */
  1528. p->RIOReadCheck = !p->RIOReadCheck;
  1529. if (copyout((caddr_t)&p->RIOReadCheck,(int)arg,
  1530. sizeof(uint))== COPYFAIL) {
  1531.  p->RIOError.Error = COPYOUT_FAILED;
  1532.  return EFAULT;
  1533. }
  1534. return 0;
  1535. case RIO_READ_REGISTER :
  1536. if (copyin((int)arg, (caddr_t)&SubCmd, 
  1537. sizeof(struct SubCmdStruct)) == COPYFAIL) {
  1538.  p->RIOError.Error = COPYIN_FAILED;
  1539.  return EFAULT;
  1540. }
  1541. rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER host %d rup %d port %d reg %xn", 
  1542. SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr);
  1543. if (SubCmd.Port > 511) {
  1544.  rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %dn", 
  1545. SubCmd.Port);
  1546.  p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  1547.  return EINVAL;
  1548. }
  1549. if (SubCmd.Rup >= MAX_RUP+LINKS_PER_UNIT ) {
  1550.  p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
  1551.  return EINVAL;
  1552. }
  1553. if (SubCmd.Host >= p->RIONumHosts ) {
  1554.  p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
  1555.  return EINVAL;
  1556. }
  1557. port = p->RIOHosts[SubCmd.Host].
  1558. UnixRups[SubCmd.Rup].BaseSysPort + SubCmd.Port;
  1559. PortP = p->RIOPortp[port];
  1560. rio_spin_lock_irqsave(&PortP->portSem, flags);
  1561. if (RIOPreemptiveCmd(p, PortP, READ_REGISTER) == RIO_FAIL) {
  1562.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER failedn");
  1563.  rio_spin_unlock_irqrestore( &PortP->portSem , flags);
  1564.  return EBUSY;
  1565. }
  1566. else
  1567.  PortP->State |= RIO_BUSY;
  1568. rio_spin_unlock_irqrestore( &PortP->portSem , flags);
  1569. if (copyout((caddr_t)&p->CdRegister, (int)arg, 
  1570. sizeof(uint)) == COPYFAIL ) {
  1571.  rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failedn");
  1572.  p->RIOError.Error = COPYOUT_FAILED;
  1573.  return EFAULT;
  1574. }
  1575. return 0;
  1576. /*
  1577. ** rio_make_dev: given port number (0-511) ORed with port type
  1578. ** (RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT) return dev_t
  1579. ** value to pass to mknod to create the correct device node.
  1580. */
  1581. case RIO_MAKE_DEV:
  1582. {
  1583. uint port = (uint)arg & RIO_MODEM_MASK;
  1584. switch ( (uint)arg & RIO_DEV_MASK ) {
  1585. case RIO_DEV_DIRECT:
  1586. arg = (caddr_t)drv_makedev(major(dev), port);
  1587. rio_dprintk (RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%xn",port, (int)arg);
  1588. return (int)arg;
  1589.   case RIO_DEV_MODEM:
  1590. arg =  (caddr_t)drv_makedev(major(dev), (port|RIO_MODEM_BIT) );
  1591. rio_dprintk (RIO_DEBUG_CTRL, "Makedev modem 0x%x is 0x%xn",port, (int)arg);
  1592. return (int)arg;
  1593. case RIO_DEV_XPRINT:
  1594. arg = (caddr_t)drv_makedev(major(dev), port);
  1595. rio_dprintk (RIO_DEBUG_CTRL, "Makedev printer 0x%x is 0x%xn",port, (int)arg);
  1596. return (int)arg;
  1597. }
  1598. rio_dprintk (RIO_DEBUG_CTRL, "MAKE Device is calledn");
  1599. return EINVAL;
  1600. }
  1601. /*
  1602. ** rio_minor: given a dev_t from a stat() call, return
  1603. ** the port number (0-511) ORed with the port type
  1604. ** ( RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT )
  1605. */
  1606. case RIO_MINOR:
  1607. {
  1608. dev_t dv;
  1609. int mino;
  1610. dv = (dev_t)((int)arg);
  1611. mino = RIO_UNMODEM(dv);
  1612. if ( RIO_ISMODEM(dv) ) {
  1613. rio_dprintk (RIO_DEBUG_CTRL, "Minor for device 0x%x: modem %dn", dv, mino);
  1614. arg = (caddr_t)(mino | RIO_DEV_MODEM);
  1615. }
  1616. else {
  1617. rio_dprintk (RIO_DEBUG_CTRL, "Minor for device 0x%x: direct %dn", dv, mino);
  1618. arg = (caddr_t)(mino | RIO_DEV_DIRECT);
  1619. }
  1620. return (int)arg;
  1621. }
  1622. }
  1623. rio_dprintk (RIO_DEBUG_CTRL, "INVALID DAEMON IOCTL 0x%xn",cmd);
  1624. p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
  1625. func_exit ();
  1626. return EINVAL;
  1627. }
  1628. /*
  1629. ** Pre-emptive commands go on RUPs and are only one byte long.
  1630. */
  1631. int
  1632. RIOPreemptiveCmd(p, PortP, Cmd)
  1633. struct rio_info * p;
  1634. struct Port *PortP;
  1635. uchar Cmd;
  1636. {
  1637. struct CmdBlk *CmdBlkP;
  1638. struct PktCmd_M *PktCmdP;
  1639. int Ret;
  1640. ushort rup;
  1641. int port;
  1642. #ifdef CHECK
  1643. CheckPortP( PortP );
  1644. #endif
  1645. if ( PortP->State & RIO_DELETED ) {
  1646. rio_dprintk (RIO_DEBUG_CTRL, "Preemptive command to deleted RTA ignoredn");
  1647. return RIO_FAIL;
  1648. }
  1649. if (((int)((char)PortP->InUse) == -1) || ! (CmdBlkP = RIOGetCmdBlk()) ) {
  1650. rio_dprintk (RIO_DEBUG_CTRL, "Cannot allocate command block for command %d on port %dn",
  1651.        Cmd, PortP->PortNum);
  1652. return RIO_FAIL;
  1653. }
  1654. rio_dprintk (RIO_DEBUG_CTRL, "Command blk 0x%x - InUse now %dn", 
  1655.        (int)CmdBlkP,PortP->InUse);
  1656. PktCmdP = (struct PktCmd_M *)&CmdBlkP->Packet.data[0];
  1657. CmdBlkP->Packet.src_unit  = 0;
  1658. if (PortP->SecondBlock)
  1659. rup = PortP->ID2;
  1660. else
  1661. rup = PortP->RupNum;
  1662. CmdBlkP->Packet.dest_unit = rup;
  1663. CmdBlkP->Packet.src_port  = COMMAND_RUP;
  1664. CmdBlkP->Packet.dest_port = COMMAND_RUP;
  1665. CmdBlkP->Packet.len   = PKT_CMD_BIT | 2;
  1666. CmdBlkP->PostFuncP = RIOUnUse;
  1667. CmdBlkP->PostArg = (int)PortP;
  1668. PktCmdP->Command = Cmd;
  1669. port = PortP->HostPort % (ushort)PORTS_PER_RTA;
  1670. /*
  1671. ** Index ports 8-15 for 2nd block of 16 port RTA.
  1672. */
  1673. if (PortP->SecondBlock)
  1674. port += (ushort) PORTS_PER_RTA;
  1675. PktCmdP->PhbNum    = port;
  1676. switch ( Cmd ) {
  1677. case MEMDUMP:
  1678. rio_dprintk (RIO_DEBUG_CTRL, "Queue MEMDUMP command blk 0x%x (addr 0x%x)n",
  1679.        (int)CmdBlkP, (int)SubCmd.Addr);
  1680. PktCmdP->SubCommand = MEMDUMP;
  1681. PktCmdP->SubAddr = SubCmd.Addr;
  1682. break;
  1683. case FCLOSE:
  1684. rio_dprintk (RIO_DEBUG_CTRL, "Queue FCLOSE command blk 0x%xn",(int)CmdBlkP);
  1685. break;
  1686. case READ_REGISTER:
  1687. rio_dprintk (RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) command blk 0x%xn",
  1688.   (int)SubCmd.Addr, (int)CmdBlkP);
  1689. PktCmdP->SubCommand = READ_REGISTER;
  1690. PktCmdP->SubAddr = SubCmd.Addr;
  1691. break;
  1692. case RESUME:
  1693. rio_dprintk (RIO_DEBUG_CTRL, "Queue RESUME command blk 0x%xn",(int)CmdBlkP);
  1694. break;
  1695. case RFLUSH:
  1696. rio_dprintk (RIO_DEBUG_CTRL, "Queue RFLUSH command blk 0x%xn",(int)CmdBlkP);
  1697. CmdBlkP->PostFuncP = RIORFlushEnable;
  1698. break;
  1699. case SUSPEND:
  1700. rio_dprintk (RIO_DEBUG_CTRL, "Queue SUSPEND command blk 0x%xn",(int)CmdBlkP);
  1701. break;
  1702. case MGET :
  1703. rio_dprintk (RIO_DEBUG_CTRL, "Queue MGET command blk 0x%xn", (int)CmdBlkP);
  1704. break;
  1705. case MSET :
  1706. case MBIC :
  1707. case MBIS :
  1708. CmdBlkP->Packet.data[4] = (char) PortP->ModemLines;
  1709. rio_dprintk (RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command blk 0x%xn", (int)CmdBlkP);
  1710. break;
  1711. case WFLUSH:
  1712. /*
  1713. ** If we have queued up the maximum number of Write flushes
  1714. ** allowed then we should not bother sending any more to the
  1715. ** RTA.
  1716. */
  1717. if ((int)((char)PortP->WflushFlag) == (int)-1) {
  1718. rio_dprintk (RIO_DEBUG_CTRL, "Trashed WFLUSH, WflushFlag about to wrap!");
  1719. RIOFreeCmdBlk(CmdBlkP);
  1720. return(RIO_FAIL);
  1721. } else {
  1722. rio_dprintk (RIO_DEBUG_CTRL, "Queue WFLUSH command blk 0x%xn",
  1723.        (int)CmdBlkP);
  1724. CmdBlkP->PostFuncP = RIOWFlushMark;
  1725. }
  1726. break;
  1727. }
  1728. PortP->InUse++;
  1729. Ret = RIOQueueCmdBlk( PortP->HostP, rup, CmdBlkP );
  1730. return Ret;
  1731. }