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