Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[linux-2.6] / 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                 return -EPERM;
312
313         case RIO_ALL_MODEM:
314                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_ALL_MODEM\n");
315                 p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
316                 return -EINVAL;
317
318         case RIO_GET_TABLE:
319                 /*
320                  ** Read the routing table from the device driver to user space
321                  */
322                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE\n");
323
324                 if ((retval = RIOApel(p)) != 0)
325                         return retval;
326
327                 if (copyout((caddr_t) p->RIOConnectTable, (int) arg, TOTAL_MAP_ENTRIES * sizeof(struct Map)) == COPYFAIL) {
328                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n");
329                         p->RIOError.Error = COPYOUT_FAILED;
330                         return -EFAULT;
331                 }
332
333                 {
334                         int entry;
335                         rio_dprintk(RIO_DEBUG_CTRL, "*****\nMAP ENTRIES\n");
336                         for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) {
337                                 if ((p->RIOConnectTable[entry].ID == 0) && (p->RIOConnectTable[entry].HostUniqueNum == 0) && (p->RIOConnectTable[entry].RtaUniqueNum == 0))
338                                         continue;
339
340                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum);
341                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum);
342                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID);
343                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2);
344                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Flags = 0x%x\n", entry, (int) p->RIOConnectTable[entry].Flags);
345                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.SysPort = 0x%x\n", entry, (int) p->RIOConnectTable[entry].SysPort);
346                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit);
347                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link);
348                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit);
349                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link);
350                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit);
351                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link);
352                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit);
353                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link);
354                                 rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name);
355                         }
356                         rio_dprintk(RIO_DEBUG_CTRL, "*****\nEND MAP ENTRIES\n");
357                 }
358                 p->RIOQuickCheck = NOT_CHANGED; /* a table has been gotten */
359                 return 0;
360
361         case RIO_PUT_TABLE:
362                 /*
363                  ** Write the routing table to the device driver from user space
364                  */
365                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE\n");
366
367                 if (!su) {
368                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE !Root\n");
369                         p->RIOError.Error = NOT_SUPER_USER;
370                         return -EPERM;
371                 }
372                 if (copyin((int) arg, (caddr_t) & p->RIOConnectTable[0], TOTAL_MAP_ENTRIES * sizeof(struct Map)) == COPYFAIL) {
373                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n");
374                         p->RIOError.Error = COPYIN_FAILED;
375                         return -EFAULT;
376                 }
377 /*
378 ***********************************
379                                 {
380                                         int entry;
381                                         rio_dprint(RIO_DEBUG_CTRL,  ("*****\nMAP ENTRIES\n") );
382                                         for ( entry=0; entry<TOTAL_MAP_ENTRIES; entry++ )
383                                         {
384                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum ) );
385                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum ) );
386                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID ) );
387                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 ) );
388                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Flags = 0x%x\n", entry, p->RIOConnectTable[entry].Flags ) );
389                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.SysPort = 0x%x\n", entry, p->RIOConnectTable[entry].SysPort ) );
390                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[0].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[0].Unit ) );
391                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[0].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[0].Link ) );
392                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[1].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[1].Unit ) );
393                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[1].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[1].Link ) );
394                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[2].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[2].Unit ) );
395                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[2].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[2].Link ) );
396                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[3].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[3].Unit ) );
397                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[4].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[3].Link ) );
398                                                 rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name ) );
399                                         }
400                                         rio_dprint(RIO_DEBUG_CTRL,  ("*****\nEND MAP ENTRIES\n") );
401                                 }
402 ***********************************
403 */
404                 return RIONewTable(p);
405
406         case RIO_GET_BINDINGS:
407                 /*
408                  ** Send bindings table, containing unique numbers of RTAs owned
409                  ** by this system to user space
410                  */
411                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS\n");
412
413                 if (!su) {
414                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS !Root\n");
415                         p->RIOError.Error = NOT_SUPER_USER;
416                         return -EPERM;
417                 }
418                 if (copyout((caddr_t) p->RIOBindTab, (int) arg, (sizeof(ulong) * MAX_RTA_BINDINGS)) == COPYFAIL) {
419                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n");
420                         p->RIOError.Error = COPYOUT_FAILED;
421                         return -EFAULT;
422                 }
423                 return 0;
424
425         case RIO_PUT_BINDINGS:
426                 /*
427                  ** Receive a bindings table, containing unique numbers of RTAs owned
428                  ** by this system
429                  */
430                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS\n");
431
432                 if (!su) {
433                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS !Root\n");
434                         p->RIOError.Error = NOT_SUPER_USER;
435                         return -EPERM;
436                 }
437                 if (copyin((int) arg, (caddr_t) & p->RIOBindTab[0], (sizeof(ulong) * MAX_RTA_BINDINGS)) == COPYFAIL) {
438                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n");
439                         p->RIOError.Error = COPYIN_FAILED;
440                         return -EFAULT;
441                 }
442                 return 0;
443
444         case RIO_BIND_RTA:
445                 {
446                         int EmptySlot = -1;
447                         /*
448                          ** Bind this RTA to host, so that it will be booted by
449                          ** host in 'boot owned RTAs' mode.
450                          */
451                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA\n");
452
453                         if (!su) {
454                                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA !Root\n");
455                                 p->RIOError.Error = NOT_SUPER_USER;
456                                 return -EPERM;
457                         }
458                         for (Entry = 0; Entry < MAX_RTA_BINDINGS; Entry++) {
459                                 if ((EmptySlot == -1) && (p->RIOBindTab[Entry] == 0L))
460                                         EmptySlot = Entry;
461                                 else if (p->RIOBindTab[Entry] == (int) arg) {
462                                         /*
463                                          ** Already exists - delete
464                                          */
465                                         p->RIOBindTab[Entry] = 0L;
466                                         rio_dprintk(RIO_DEBUG_CTRL, "Removing Rta %x from p->RIOBindTab\n", (int) arg);
467                                         return 0;
468                                 }
469                         }
470                         /*
471                          ** Dosen't exist - add
472                          */
473                         if (EmptySlot != -1) {
474                                 p->RIOBindTab[EmptySlot] = (int) arg;
475                                 rio_dprintk(RIO_DEBUG_CTRL, "Adding Rta %x to p->RIOBindTab\n", (int) arg);
476                         } else {
477                                 rio_dprintk(RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %x not added\n", (int) arg);
478                                 return -ENOMEM;
479                         }
480                         return 0;
481                 }
482
483         case RIO_RESUME:
484                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME\n");
485                 port = (uint) arg;
486                 if ((port < 0) || (port > 511)) {
487                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port);
488                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
489                         return -EINVAL;
490                 }
491                 PortP = p->RIOPortp[port];
492                 if (!PortP->Mapped) {
493                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not mapped\n", port);
494                         p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;
495                         return -EINVAL;
496                 }
497                 if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) {
498                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not open\n", port);
499                         return -EINVAL;
500                 }
501
502                 rio_spin_lock_irqsave(&PortP->portSem, flags);
503                 if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RESUME) == RIO_FAIL) {
504                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME failed\n");
505                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
506                         return -EBUSY;
507                 } else {
508                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d resumed\n", port);
509                         PortP->State |= RIO_BUSY;
510                 }
511                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
512                 return retval;
513
514         case RIO_ASSIGN_RTA:
515                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA\n");
516                 if (!su) {
517                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA !Root\n");
518                         p->RIOError.Error = NOT_SUPER_USER;
519                         return -EPERM;
520                 }
521                 if (copyin((int) arg, (caddr_t) & MapEnt, sizeof(MapEnt))
522                     == COPYFAIL) {
523                         rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n");
524                         p->RIOError.Error = COPYIN_FAILED;
525                         return -EFAULT;
526                 }
527                 return RIOAssignRta(p, &MapEnt);
528
529         case RIO_CHANGE_NAME:
530                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME\n");
531                 if (!su) {
532                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME !Root\n");
533                         p->RIOError.Error = NOT_SUPER_USER;
534                         return -EPERM;
535                 }
536                 if (copyin((int) arg, (caddr_t) & MapEnt, sizeof(MapEnt))
537                     == COPYFAIL) {
538                         rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n");
539                         p->RIOError.Error = COPYIN_FAILED;
540                         return -EFAULT;
541                 }
542                 return RIOChangeName(p, &MapEnt);
543
544         case RIO_DELETE_RTA:
545                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA\n");
546                 if (!su) {
547                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA !Root\n");
548                         p->RIOError.Error = NOT_SUPER_USER;
549                         return -EPERM;
550                 }
551                 if (copyin((int) arg, (caddr_t) & MapEnt, sizeof(MapEnt))
552                     == COPYFAIL) {
553                         rio_dprintk(RIO_DEBUG_CTRL, "Copy from data space failed\n");
554                         p->RIOError.Error = COPYIN_FAILED;
555                         return -EFAULT;
556                 }
557                 return RIODeleteRta(p, &MapEnt);
558
559         case RIO_QUICK_CHECK:
560                 /*
561                  ** 09.12.1998 ARG - ESIL 0776 part fix
562                  ** A customer was using this to get the RTAs
563                  ** connect/disconnect status.
564                  ** RIOConCon() had been botched use RIOHalted
565                  ** to keep track of RTA connections and
566                  ** disconnections. That has been changed and
567                  ** RIORtaDisCons in the rio_info struct now
568                  ** does the job. So we need to return the value
569                  ** of RIORtaCons instead of RIOHalted.
570                  **
571                  if (copyout((caddr_t)&p->RIOHalted,(int)arg,
572                  sizeof(uint))==COPYFAIL) {
573                  **
574                  */
575
576                 if (copyout((caddr_t) & p->RIORtaDisCons, (int) arg, sizeof(uint)) == COPYFAIL) {
577                         p->RIOError.Error = COPYOUT_FAILED;
578                         return -EFAULT;
579                 }
580                 return 0;
581
582         case RIO_LAST_ERROR:
583                 if (copyout((caddr_t) & p->RIOError, (int) arg, sizeof(struct Error)) == COPYFAIL)
584                         return -EFAULT;
585                 return 0;
586
587         case RIO_GET_LOG:
588                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_LOG\n");
589                 return -EINVAL;
590
591         case RIO_GET_MODTYPE:
592                 if (copyin((int) arg, (caddr_t) & port, sizeof(uint)) == COPYFAIL) {
593                         p->RIOError.Error = COPYIN_FAILED;
594                         return -EFAULT;
595                 }
596                 rio_dprintk(RIO_DEBUG_CTRL, "Get module type for port %d\n", port);
597                 if (port < 0 || port > 511) {
598                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Bad port number %d\n", port);
599                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
600                         return -EINVAL;
601                 }
602                 PortP = (p->RIOPortp[port]);
603                 if (!PortP->Mapped) {
604                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Port %d not mapped\n", port);
605                         p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;
606                         return -EINVAL;
607                 }
608                 /*
609                  ** Return module type of port
610                  */
611                 port = PortP->HostP->UnixRups[PortP->RupNum].ModTypes;
612                 if (copyout((caddr_t) & port, (int) arg, sizeof(uint)) == COPYFAIL) {
613                         p->RIOError.Error = COPYOUT_FAILED;
614                         return -EFAULT;
615                 }
616                 return (0);
617                 /*
618                  ** 02.03.1999 ARG - ESIL 0820 fix
619                  ** We are no longer using "Boot Mode", so these ioctls
620                  ** are not required :
621                  **
622                  case RIO_GET_BOOT_MODE :
623                  rio_dprint(RIO_DEBUG_CTRL, ("Get boot mode - %x\n", p->RIOBootMode));
624                  **
625                  ** Return boot state of system - BOOT_ALL, BOOT_OWN or BOOT_NONE
626                  **
627                  if (copyout((caddr_t)&p->RIOBootMode, (int)arg,
628                  sizeof(p->RIOBootMode)) == COPYFAIL) {
629                  p->RIOError.Error = COPYOUT_FAILED;
630                  return -EFAULT;
631                  }
632                  return(0);
633
634                  case RIO_SET_BOOT_MODE :
635                  p->RIOBootMode = (uint) arg;
636                  rio_dprint(RIO_DEBUG_CTRL, ("Set boot mode to 0x%x\n", p->RIOBootMode));
637                  return(0);
638                  **
639                  ** End ESIL 0820 fix
640                  */
641
642         case RIO_BLOCK_OPENS:
643                 rio_dprintk(RIO_DEBUG_CTRL, "Opens block until booted\n");
644                 for (Entry = 0; Entry < RIO_PORTS; Entry++) {
645                         rio_spin_lock_irqsave(&PortP->portSem, flags);
646                         p->RIOPortp[Entry]->WaitUntilBooted = 1;
647                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
648                 }
649                 return 0;
650
651         case RIO_SETUP_PORTS:
652                 rio_dprintk(RIO_DEBUG_CTRL, "Setup ports\n");
653                 if (copyin((int) arg, (caddr_t) & PortSetup, sizeof(PortSetup))
654                     == COPYFAIL) {
655                         p->RIOError.Error = COPYIN_FAILED;
656                         rio_dprintk(RIO_DEBUG_CTRL, "EFAULT");
657                         return -EFAULT;
658                 }
659                 if (PortSetup.From > PortSetup.To || PortSetup.To >= RIO_PORTS) {
660                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
661                         rio_dprintk(RIO_DEBUG_CTRL, "ENXIO");
662                         return -ENXIO;
663                 }
664                 if (PortSetup.XpCps > p->RIOConf.MaxXpCps || PortSetup.XpCps < p->RIOConf.MinXpCps) {
665                         p->RIOError.Error = XPRINT_CPS_OUT_OF_RANGE;
666                         rio_dprintk(RIO_DEBUG_CTRL, "EINVAL");
667                         return -EINVAL;
668                 }
669                 if (!p->RIOPortp) {
670                         cprintf("No p->RIOPortp array!\n");
671                         rio_dprintk(RIO_DEBUG_CTRL, "No p->RIOPortp array!\n");
672                         return -EIO;
673                 }
674                 rio_dprintk(RIO_DEBUG_CTRL, "entering loop (%d %d)!\n", PortSetup.From, PortSetup.To);
675                 for (loop = PortSetup.From; loop <= PortSetup.To; loop++) {
676                         rio_dprintk(RIO_DEBUG_CTRL, "in loop (%d)!\n", loop);
677                 }
678                 rio_dprintk(RIO_DEBUG_CTRL, "after loop (%d)!\n", loop);
679                 rio_dprintk(RIO_DEBUG_CTRL, "Retval:%x\n", retval);
680                 return retval;
681
682         case RIO_GET_PORT_SETUP:
683                 rio_dprintk(RIO_DEBUG_CTRL, "Get port setup\n");
684                 if (copyin((int) arg, (caddr_t) & PortSetup, sizeof(PortSetup))
685                     == COPYFAIL) {
686                         p->RIOError.Error = COPYIN_FAILED;
687                         return -EFAULT;
688                 }
689                 if (PortSetup.From >= RIO_PORTS) {
690                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
691                         return -ENXIO;
692                 }
693
694                 port = PortSetup.To = PortSetup.From;
695                 PortSetup.IxAny = (p->RIOPortp[port]->Config & RIO_IXANY) ? 1 : 0;
696                 PortSetup.IxOn = (p->RIOPortp[port]->Config & RIO_IXON) ? 1 : 0;
697                 PortSetup.Drain = (p->RIOPortp[port]->Config & RIO_WAITDRAIN) ? 1 : 0;
698                 PortSetup.Store = p->RIOPortp[port]->Store;
699                 PortSetup.Lock = p->RIOPortp[port]->Lock;
700                 PortSetup.XpCps = p->RIOPortp[port]->Xprint.XpCps;
701                 bcopy(p->RIOPortp[port]->Xprint.XpOn, PortSetup.XpOn, MAX_XP_CTRL_LEN);
702                 bcopy(p->RIOPortp[port]->Xprint.XpOff, PortSetup.XpOff, MAX_XP_CTRL_LEN);
703                 PortSetup.XpOn[MAX_XP_CTRL_LEN - 1] = '\0';
704                 PortSetup.XpOff[MAX_XP_CTRL_LEN - 1] = '\0';
705
706                 if (copyout((caddr_t) & PortSetup, (int) arg, sizeof(PortSetup))
707                     == COPYFAIL) {
708                         p->RIOError.Error = COPYOUT_FAILED;
709                         return -EFAULT;
710                 }
711                 return retval;
712
713         case RIO_GET_PORT_PARAMS:
714                 rio_dprintk(RIO_DEBUG_CTRL, "Get port params\n");
715                 if (copyin((int) arg, (caddr_t) & PortParams, sizeof(struct PortParams)) == COPYFAIL) {
716                         p->RIOError.Error = COPYIN_FAILED;
717                         return -EFAULT;
718                 }
719                 if (PortParams.Port >= RIO_PORTS) {
720                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
721                         return -ENXIO;
722                 }
723                 PortP = (p->RIOPortp[PortParams.Port]);
724                 PortParams.Config = PortP->Config;
725                 PortParams.State = PortP->State;
726                 rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port);
727
728                 if (copyout((caddr_t) & PortParams, (int) arg, sizeof(struct PortParams)) == COPYFAIL) {
729                         p->RIOError.Error = COPYOUT_FAILED;
730                         return -EFAULT;
731                 }
732                 return retval;
733
734         case RIO_GET_PORT_TTY:
735                 rio_dprintk(RIO_DEBUG_CTRL, "Get port tty\n");
736                 if (copyin((int) arg, (caddr_t) & PortTty, sizeof(struct PortTty))
737                     == COPYFAIL) {
738                         p->RIOError.Error = COPYIN_FAILED;
739                         return -EFAULT;
740                 }
741                 if (PortTty.port >= RIO_PORTS) {
742                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
743                         return -ENXIO;
744                 }
745
746                 rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortTty.port);
747                 PortP = (p->RIOPortp[PortTty.port]);
748                 if (copyout((caddr_t) & PortTty, (int) arg, sizeof(struct PortTty)) == COPYFAIL) {
749                         p->RIOError.Error = COPYOUT_FAILED;
750                         return -EFAULT;
751                 }
752                 return retval;
753
754         case RIO_SET_PORT_TTY:
755                 if (copyin((int) arg, (caddr_t) & PortTty, sizeof(struct PortTty)) == COPYFAIL) {
756                         p->RIOError.Error = COPYIN_FAILED;
757                         return -EFAULT;
758                 }
759                 rio_dprintk(RIO_DEBUG_CTRL, "Set port %d tty\n", PortTty.port);
760                 if (PortTty.port >= (ushort) RIO_PORTS) {
761                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
762                         return -ENXIO;
763                 }
764                 PortP = (p->RIOPortp[PortTty.port]);
765                 RIOParam(PortP, CONFIG, PortP->State & RIO_MODEM, OK_TO_SLEEP);
766                 return retval;
767
768         case RIO_SET_PORT_PARAMS:
769                 rio_dprintk(RIO_DEBUG_CTRL, "Set port params\n");
770                 if (copyin((int) arg, (caddr_t) & PortParams, sizeof(PortParams))
771                     == COPYFAIL) {
772                         p->RIOError.Error = COPYIN_FAILED;
773                         return -EFAULT;
774                 }
775                 if (PortParams.Port >= (ushort) RIO_PORTS) {
776                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
777                         return -ENXIO;
778                 }
779                 PortP = (p->RIOPortp[PortParams.Port]);
780                 rio_spin_lock_irqsave(&PortP->portSem, flags);
781                 PortP->Config = PortParams.Config;
782                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
783                 return retval;
784
785         case RIO_GET_PORT_STATS:
786                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n");
787                 if (copyin((int) arg, (caddr_t) & portStats, sizeof(struct portStats)) == COPYFAIL) {
788                         p->RIOError.Error = COPYIN_FAILED;
789                         return -EFAULT;
790                 }
791                 if (portStats.port >= RIO_PORTS) {
792                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
793                         return -ENXIO;
794                 }
795                 PortP = (p->RIOPortp[portStats.port]);
796                 portStats.gather = PortP->statsGather;
797                 portStats.txchars = PortP->txchars;
798                 portStats.rxchars = PortP->rxchars;
799                 portStats.opens = PortP->opens;
800                 portStats.closes = PortP->closes;
801                 portStats.ioctls = PortP->ioctls;
802                 if (copyout((caddr_t) & portStats, (int) arg, sizeof(struct portStats)) == COPYFAIL) {
803                         p->RIOError.Error = COPYOUT_FAILED;
804                         return -EFAULT;
805                 }
806                 return retval;
807
808         case RIO_RESET_PORT_STATS:
809                 port = (uint) arg;
810                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n");
811                 if (port >= RIO_PORTS) {
812                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
813                         return -ENXIO;
814                 }
815                 PortP = (p->RIOPortp[port]);
816                 rio_spin_lock_irqsave(&PortP->portSem, flags);
817                 PortP->txchars = 0;
818                 PortP->rxchars = 0;
819                 PortP->opens = 0;
820                 PortP->closes = 0;
821                 PortP->ioctls = 0;
822                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
823                 return retval;
824
825         case RIO_GATHER_PORT_STATS:
826                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n");
827                 if (copyin((int) arg, (caddr_t) & portStats, sizeof(struct portStats)) == COPYFAIL) {
828                         p->RIOError.Error = COPYIN_FAILED;
829                         return -EFAULT;
830                 }
831                 if (portStats.port >= RIO_PORTS) {
832                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
833                         return -ENXIO;
834                 }
835                 PortP = (p->RIOPortp[portStats.port]);
836                 rio_spin_lock_irqsave(&PortP->portSem, flags);
837                 PortP->statsGather = portStats.gather;
838                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
839                 return retval;
840
841         case RIO_READ_CONFIG:
842                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n");
843                 if (copyout((caddr_t) & p->RIOConf, (int) arg, sizeof(struct Conf)) == COPYFAIL) {
844                         p->RIOError.Error = COPYOUT_FAILED;
845                         return -EFAULT;
846                 }
847                 return retval;
848
849         case RIO_SET_CONFIG:
850                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_CONFIG\n");
851                 if (!su) {
852                         p->RIOError.Error = NOT_SUPER_USER;
853                         return -EPERM;
854                 }
855                 if (copyin((int) arg, (caddr_t) & p->RIOConf, sizeof(struct Conf))
856                     == COPYFAIL) {
857                         p->RIOError.Error = COPYIN_FAILED;
858                         return -EFAULT;
859                 }
860                 /*
861                  ** move a few value around
862                  */
863                 for (Host = 0; Host < p->RIONumHosts; Host++)
864                         if ((p->RIOHosts[Host].Flags & RUN_STATE) == RC_RUNNING)
865                                 WWORD(p->RIOHosts[Host].ParmMapP->timer, p->RIOConf.Timer);
866                 return retval;
867
868         case RIO_START_POLLER:
869                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_START_POLLER\n");
870                 return -EINVAL;
871
872         case RIO_STOP_POLLER:
873                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_STOP_POLLER\n");
874                 if (!su) {
875                         p->RIOError.Error = NOT_SUPER_USER;
876                         return -EPERM;
877                 }
878                 p->RIOPolling = NOT_POLLING;
879                 return retval;
880
881         case RIO_SETDEBUG:
882         case RIO_GETDEBUG:
883                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n");
884                 if (copyin((int) arg, (caddr_t) & DebugCtrl, sizeof(DebugCtrl))
885                     == COPYFAIL) {
886                         p->RIOError.Error = COPYIN_FAILED;
887                         return -EFAULT;
888                 }
889                 if (DebugCtrl.SysPort == NO_PORT) {
890                         if (cmd == RIO_SETDEBUG) {
891                                 if (!su) {
892                                         p->RIOError.Error = NOT_SUPER_USER;
893                                         return -EPERM;
894                                 }
895                                 p->rio_debug = DebugCtrl.Debug;
896                                 p->RIODebugWait = DebugCtrl.Wait;
897                                 rio_dprintk(RIO_DEBUG_CTRL, "Set global debug to 0x%x set wait to 0x%x\n", p->rio_debug, p->RIODebugWait);
898                         } else {
899                                 rio_dprintk(RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n", p->rio_debug, p->RIODebugWait);
900                                 DebugCtrl.Debug = p->rio_debug;
901                                 DebugCtrl.Wait = p->RIODebugWait;
902                                 if (copyout((caddr_t) & DebugCtrl, (int) arg, sizeof(DebugCtrl)) == COPYFAIL) {
903                                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort);
904                                         p->RIOError.Error = COPYOUT_FAILED;
905                                         return -EFAULT;
906                                 }
907                         }
908                 } else if (DebugCtrl.SysPort >= RIO_PORTS && DebugCtrl.SysPort != NO_PORT) {
909                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort);
910                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
911                         return -ENXIO;
912                 } else if (cmd == RIO_SETDEBUG) {
913                         if (!su) {
914                                 p->RIOError.Error = NOT_SUPER_USER;
915                                 return -EPERM;
916                         }
917                         rio_spin_lock_irqsave(&PortP->portSem, flags);
918                         p->RIOPortp[DebugCtrl.SysPort]->Debug = DebugCtrl.Debug;
919                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
920                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug);
921                 } else {
922                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug);
923                         DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug;
924                         if (copyout((caddr_t) & DebugCtrl, (int) arg, sizeof(DebugCtrl)) == COPYFAIL) {
925                                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n");
926                                 p->RIOError.Error = COPYOUT_FAILED;
927                                 return -EFAULT;
928                         }
929                 }
930                 return retval;
931
932         case RIO_VERSID:
933                 /*
934                  ** Enquire about the release and version.
935                  ** We return MAX_VERSION_LEN bytes, being a
936                  ** textual null terminated string.
937                  */
938                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID\n");
939                 if (copyout((caddr_t) RIOVersid(), (int) arg, sizeof(struct rioVersion)) == COPYFAIL) {
940                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID: Bad copy to user space (host=%d)\n", Host);
941                         p->RIOError.Error = COPYOUT_FAILED;
942                         return -EFAULT;
943                 }
944                 return retval;
945
946                 /*
947                  ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
948                  ** !! commented out previous 'RIO_VERSID' functionality !!
949                  ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
950                  **
951                  case RIO_VERSID:
952                  **
953                  ** Enquire about the release and version.
954                  ** We return MAX_VERSION_LEN bytes, being a textual null
955                  ** terminated string.
956                  **
957                  rio_dprint(RIO_DEBUG_CTRL, ("RIO_VERSID\n"));
958                  if (copyout((caddr_t)RIOVersid(),
959                  (int)arg, MAX_VERSION_LEN ) == COPYFAIL ) {
960                  rio_dprint(RIO_DEBUG_CTRL, ("RIO_VERSID: Bad copy to user space\n",Host));
961                  p->RIOError.Error = COPYOUT_FAILED;
962                  return -EFAULT;
963                  }
964                  return retval;
965                  **
966                  ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
967                  */
968
969         case RIO_NUM_HOSTS:
970                 /*
971                  ** Enquire as to the number of hosts located
972                  ** at init time.
973                  */
974                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n");
975                 if (copyout((caddr_t) & p->RIONumHosts, (int) arg, sizeof(p->RIONumHosts)) == COPYFAIL) {
976                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n");
977                         p->RIOError.Error = COPYOUT_FAILED;
978                         return -EFAULT;
979                 }
980                 return retval;
981
982         case RIO_HOST_FOAD:
983                 /*
984                  ** Kill host. This may not be in the final version...
985                  */
986                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD %d\n", (int) arg);
987                 if (!su) {
988                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n");
989                         p->RIOError.Error = NOT_SUPER_USER;
990                         return -EPERM;
991                 }
992                 p->RIOHalted = 1;
993                 p->RIOSystemUp = 0;
994
995                 for (Host = 0; Host < p->RIONumHosts; Host++) {
996                         (void) RIOBoardTest(p->RIOHosts[Host].PaddrP, p->RIOHosts[Host].Caddr, p->RIOHosts[Host].Type, p->RIOHosts[Host].Slot);
997                         bzero((caddr_t) & p->RIOHosts[Host].Flags, ((int) &p->RIOHosts[Host].____end_marker____) - ((int) &p->RIOHosts[Host].Flags));
998                         p->RIOHosts[Host].Flags = RC_WAITING;
999                 }
1000                 RIOFoadWakeup(p);
1001                 p->RIONumBootPkts = 0;
1002                 p->RIOBooting = 0;
1003                 printk("HEEEEELP!\n");
1004
1005                 for (loop = 0; loop < RIO_PORTS; loop++) {
1006                         spin_lock_init(&p->RIOPortp[loop]->portSem);
1007                         p->RIOPortp[loop]->InUse = NOT_INUSE;
1008                 }
1009
1010                 p->RIOSystemUp = 0;
1011                 return retval;
1012
1013         case RIO_DOWNLOAD:
1014                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD\n");
1015                 if (!su) {
1016                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Not super user\n");
1017                         p->RIOError.Error = NOT_SUPER_USER;
1018                         return -EPERM;
1019                 }
1020                 if (copyin((int) arg, (caddr_t) & DownLoad, sizeof(DownLoad)) == COPYFAIL) {
1021                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n");
1022                         p->RIOError.Error = COPYIN_FAILED;
1023                         return -EFAULT;
1024                 }
1025                 rio_dprintk(RIO_DEBUG_CTRL, "Copied in download code for product code 0x%x\n", DownLoad.ProductCode);
1026
1027                 /*
1028                  ** It is important that the product code is an unsigned object!
1029                  */
1030                 if (DownLoad.ProductCode > MAX_PRODUCT) {
1031                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passed\n", DownLoad.ProductCode);
1032                         p->RIOError.Error = NO_SUCH_PRODUCT;
1033                         return -ENXIO;
1034                 }
1035                 /*
1036                  ** do something!
1037                  */
1038                 retval = (*(RIOBootTable[DownLoad.ProductCode])) (p, &DownLoad);
1039                 /* <-- Panic */
1040                 p->RIOHalted = 0;
1041                 /*
1042                  ** and go back, content with a job well completed.
1043                  */
1044                 return retval;
1045
1046         case RIO_PARMS:
1047                 {
1048                         uint host;
1049
1050                         if (copyin((int) arg, (caddr_t) & host, sizeof(host)) == COPYFAIL) {
1051                                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n");
1052                                 p->RIOError.Error = COPYIN_FAILED;
1053                                 return -EFAULT;
1054                         }
1055                         /*
1056                          ** Fetch the parmmap
1057                          */
1058                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS\n");
1059                         if (copyout((caddr_t) p->RIOHosts[host].ParmMapP, (int) arg, sizeof(PARM_MAP)) == COPYFAIL) {
1060                                 p->RIOError.Error = COPYOUT_FAILED;
1061                                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n");
1062                                 return -EFAULT;
1063                         }
1064                 }
1065                 return retval;
1066
1067         case RIO_HOST_REQ:
1068                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ\n");
1069                 if (copyin((int) arg, (caddr_t) & HostReq, sizeof(HostReq)) == COPYFAIL) {
1070                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n");
1071                         p->RIOError.Error = COPYIN_FAILED;
1072                         return -EFAULT;
1073                 }
1074                 if (HostReq.HostNum >= p->RIONumHosts) {
1075                         p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
1076                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Illegal host number %d\n", HostReq.HostNum);
1077                         return -ENXIO;
1078                 }
1079                 rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostReq.HostNum);
1080
1081                 if (copyout((caddr_t) & p->RIOHosts[HostReq.HostNum], (int) HostReq.HostP, sizeof(struct Host)) == COPYFAIL) {
1082                         p->RIOError.Error = COPYOUT_FAILED;
1083                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Bad copy to user space\n");
1084                         return -EFAULT;
1085                 }
1086                 return retval;
1087
1088         case RIO_HOST_DPRAM:
1089                 rio_dprintk(RIO_DEBUG_CTRL, "Request for DPRAM\n");
1090                 if (copyin((int) arg, (caddr_t) & HostDpRam, sizeof(HostDpRam)) == COPYFAIL) {
1091                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n");
1092                         p->RIOError.Error = COPYIN_FAILED;
1093                         return -EFAULT;
1094                 }
1095                 if (HostDpRam.HostNum >= p->RIONumHosts) {
1096                         p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
1097                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Illegal host number %d\n", HostDpRam.HostNum);
1098                         return -ENXIO;
1099                 }
1100                 rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostDpRam.HostNum);
1101
1102                 if (p->RIOHosts[HostDpRam.HostNum].Type == RIO_PCI) {
1103                         int off;
1104                         /* It's hardware like this that really gets on my tits. */
1105                         static unsigned char copy[sizeof(struct DpRam)];
1106                         for (off = 0; off < sizeof(struct DpRam); off++)
1107                                 copy[off] = p->RIOHosts[HostDpRam.HostNum].Caddr[off];
1108                         if (copyout((caddr_t) copy, (int) HostDpRam.DpRamP, sizeof(struct DpRam)) == COPYFAIL) {
1109                                 p->RIOError.Error = COPYOUT_FAILED;
1110                                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
1111                                 return -EFAULT;
1112                         }
1113                 } else if (copyout((caddr_t) p->RIOHosts[HostDpRam.HostNum].Caddr, (int) HostDpRam.DpRamP, sizeof(struct DpRam)) == COPYFAIL) {
1114                         p->RIOError.Error = COPYOUT_FAILED;
1115                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
1116                         return -EFAULT;
1117                 }
1118                 return retval;
1119
1120         case RIO_SET_BUSY:
1121                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY\n");
1122                 if ((int) arg < 0 || (int) arg > 511) {
1123                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %d\n", (int) arg);
1124                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
1125                         return -EINVAL;
1126                 }
1127                 rio_spin_lock_irqsave(&PortP->portSem, flags);
1128                 p->RIOPortp[(int) arg]->State |= RIO_BUSY;
1129                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1130                 return retval;
1131
1132         case RIO_HOST_PORT:
1133                 /*
1134                  ** The daemon want port information
1135                  ** (probably for debug reasons)
1136                  */
1137                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT\n");
1138                 if (copyin((int) arg, (caddr_t) & PortReq, sizeof(PortReq)) == COPYFAIL) {
1139                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n");
1140                         p->RIOError.Error = COPYIN_FAILED;
1141                         return -EFAULT;
1142                 }
1143
1144                 if (PortReq.SysPort >= RIO_PORTS) {     /* SysPort is unsigned */
1145                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Illegal port number %d\n", PortReq.SysPort);
1146                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
1147                         return -ENXIO;
1148                 }
1149                 rio_dprintk(RIO_DEBUG_CTRL, "Request for port %d\n", PortReq.SysPort);
1150                 if (copyout((caddr_t) p->RIOPortp[PortReq.SysPort], (int) PortReq.PortP, sizeof(struct Port)) == COPYFAIL) {
1151                         p->RIOError.Error = COPYOUT_FAILED;
1152                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Bad copy to user space\n");
1153                         return -EFAULT;
1154                 }
1155                 return retval;
1156
1157         case RIO_HOST_RUP:
1158                 /*
1159                  ** The daemon want rup information
1160                  ** (probably for debug reasons)
1161                  */
1162                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP\n");
1163                 if (copyin((int) arg, (caddr_t) & RupReq, sizeof(RupReq)) == COPYFAIL) {
1164                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n");
1165                         p->RIOError.Error = COPYIN_FAILED;
1166                         return -EFAULT;
1167                 }
1168                 if (RupReq.HostNum >= p->RIONumHosts) { /* host is unsigned */
1169                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal host number %d\n", RupReq.HostNum);
1170                         p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
1171                         return -ENXIO;
1172                 }
1173                 if (RupReq.RupNum >= MAX_RUP + LINKS_PER_UNIT) {        /* eek! */
1174                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal rup number %d\n", RupReq.RupNum);
1175                         p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
1176                         return -EINVAL;
1177                 }
1178                 HostP = &p->RIOHosts[RupReq.HostNum];
1179
1180                 if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
1181                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Host %d not running\n", RupReq.HostNum);
1182                         p->RIOError.Error = HOST_NOT_RUNNING;
1183                         return -EIO;
1184                 }
1185                 rio_dprintk(RIO_DEBUG_CTRL, "Request for rup %d from host %d\n", RupReq.RupNum, RupReq.HostNum);
1186
1187                 if (copyout((caddr_t) HostP->UnixRups[RupReq.RupNum].RupP, (int) RupReq.RupP, sizeof(struct RUP)) == COPYFAIL) {
1188                         p->RIOError.Error = COPYOUT_FAILED;
1189                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n");
1190                         return -EFAULT;
1191                 }
1192                 return retval;
1193
1194         case RIO_HOST_LPB:
1195                 /*
1196                  ** The daemon want lpb information
1197                  ** (probably for debug reasons)
1198                  */
1199                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB\n");
1200                 if (copyin((int) arg, (caddr_t) & LpbReq, sizeof(LpbReq)) == COPYFAIL) {
1201                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n");
1202                         p->RIOError.Error = COPYIN_FAILED;
1203                         return -EFAULT;
1204                 }
1205                 if (LpbReq.Host >= p->RIONumHosts) {    /* host is unsigned */
1206                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal host number %d\n", LpbReq.Host);
1207                         p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
1208                         return -ENXIO;
1209                 }
1210                 if (LpbReq.Link >= LINKS_PER_UNIT) {    /* eek! */
1211                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %d\n", LpbReq.Link);
1212                         p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE;
1213                         return -EINVAL;
1214                 }
1215                 HostP = &p->RIOHosts[LpbReq.Host];
1216
1217                 if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
1218                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not running\n", LpbReq.Host);
1219                         p->RIOError.Error = HOST_NOT_RUNNING;
1220                         return -EIO;
1221                 }
1222                 rio_dprintk(RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n", LpbReq.Link, LpbReq.Host);
1223
1224                 if (copyout((caddr_t) & HostP->LinkStrP[LpbReq.Link], (int) LpbReq.LpbP, sizeof(struct LPB)) == COPYFAIL) {
1225                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n");
1226                         p->RIOError.Error = COPYOUT_FAILED;
1227                         return -EFAULT;
1228                 }
1229                 return retval;
1230
1231                 /*
1232                  ** Here 3 IOCTL's that allow us to change the way in which
1233                  ** rio logs errors. send them just to syslog or send them
1234                  ** to both syslog and console or send them to just the console.
1235                  **
1236                  ** See RioStrBuf() in util.c for the other half.
1237                  */
1238         case RIO_SYSLOG_ONLY:
1239                 p->RIOPrintLogState = PRINT_TO_LOG;     /* Just syslog */
1240                 return 0;
1241
1242         case RIO_SYSLOG_CONS:
1243                 p->RIOPrintLogState = PRINT_TO_LOG_CONS;        /* syslog and console */
1244                 return 0;
1245
1246         case RIO_CONS_ONLY:
1247                 p->RIOPrintLogState = PRINT_TO_CONS;    /* Just console */
1248                 return 0;
1249
1250         case RIO_SIGNALS_ON:
1251                 if (p->RIOSignalProcess) {
1252                         p->RIOError.Error = SIGNALS_ALREADY_SET;
1253                         return -EBUSY;
1254                 }
1255                 p->RIOSignalProcess = getpid();
1256                 p->RIOPrintDisabled = DONT_PRINT;
1257                 return retval;
1258
1259         case RIO_SIGNALS_OFF:
1260                 if (p->RIOSignalProcess != getpid()) {
1261                         p->RIOError.Error = NOT_RECEIVING_PROCESS;
1262                         return -EPERM;
1263                 }
1264                 rio_dprintk(RIO_DEBUG_CTRL, "Clear signal process to zero\n");
1265                 p->RIOSignalProcess = 0;
1266                 return retval;
1267
1268         case RIO_SET_BYTE_MODE:
1269                 for (Host = 0; Host < p->RIONumHosts; Host++)
1270                         if (p->RIOHosts[Host].Type == RIO_AT)
1271                                 p->RIOHosts[Host].Mode &= ~WORD_OPERATION;
1272                 return retval;
1273
1274         case RIO_SET_WORD_MODE:
1275                 for (Host = 0; Host < p->RIONumHosts; Host++)
1276                         if (p->RIOHosts[Host].Type == RIO_AT)
1277                                 p->RIOHosts[Host].Mode |= WORD_OPERATION;
1278                 return retval;
1279
1280         case RIO_SET_FAST_BUS:
1281                 for (Host = 0; Host < p->RIONumHosts; Host++)
1282                         if (p->RIOHosts[Host].Type == RIO_AT)
1283                                 p->RIOHosts[Host].Mode |= FAST_AT_BUS;
1284                 return retval;
1285
1286         case RIO_SET_SLOW_BUS:
1287                 for (Host = 0; Host < p->RIONumHosts; Host++)
1288                         if (p->RIOHosts[Host].Type == RIO_AT)
1289                                 p->RIOHosts[Host].Mode &= ~FAST_AT_BUS;
1290                 return retval;
1291
1292         case RIO_MAP_B50_TO_50:
1293         case RIO_MAP_B50_TO_57600:
1294         case RIO_MAP_B110_TO_110:
1295         case RIO_MAP_B110_TO_115200:
1296                 rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping\n");
1297                 port = (uint) arg;
1298                 if (port < 0 || port > 511) {
1299                         rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port);
1300                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
1301                         return -EINVAL;
1302                 }
1303                 rio_spin_lock_irqsave(&PortP->portSem, flags);
1304                 switch (cmd) {
1305                 case RIO_MAP_B50_TO_50:
1306                         p->RIOPortp[port]->Config |= RIO_MAP_50_TO_50;
1307                         break;
1308                 case RIO_MAP_B50_TO_57600:
1309                         p->RIOPortp[port]->Config &= ~RIO_MAP_50_TO_50;
1310                         break;
1311                 case RIO_MAP_B110_TO_110:
1312                         p->RIOPortp[port]->Config |= RIO_MAP_110_TO_110;
1313                         break;
1314                 case RIO_MAP_B110_TO_115200:
1315                         p->RIOPortp[port]->Config &= ~RIO_MAP_110_TO_110;
1316                         break;
1317                 }
1318                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1319                 return retval;
1320
1321         case RIO_STREAM_INFO:
1322                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_STREAM_INFO\n");
1323                 return -EINVAL;
1324
1325         case RIO_SEND_PACKET:
1326                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n");
1327                 if (copyin((int) arg, (caddr_t) & SendPack, sizeof(SendPack)) == COPYFAIL) {
1328                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n");
1329                         p->RIOError.Error = COPYIN_FAILED;
1330                         return -EFAULT;
1331                 }
1332                 if (SendPack.PortNum >= 128) {
1333                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
1334                         return -ENXIO;
1335                 }
1336
1337                 PortP = p->RIOPortp[SendPack.PortNum];
1338                 rio_spin_lock_irqsave(&PortP->portSem, flags);
1339
1340                 if (!can_add_transmit(&PacketP, PortP)) {
1341                         p->RIOError.Error = UNIT_IS_IN_USE;
1342                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1343                         return -ENOSPC;
1344                 }
1345
1346                 for (loop = 0; loop < (ushort) (SendPack.Len & 127); loop++)
1347                         WBYTE(PacketP->data[loop], SendPack.Data[loop]);
1348
1349                 WBYTE(PacketP->len, SendPack.Len);
1350
1351                 add_transmit(PortP);
1352                 /*
1353                  ** Count characters transmitted for port statistics reporting
1354                  */
1355                 if (PortP->statsGather)
1356                         PortP->txchars += (SendPack.Len & 127);
1357                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1358                 return retval;
1359
1360         case RIO_NO_MESG:
1361                 if (su)
1362                         p->RIONoMessage = 1;
1363                 return su ? 0 : -EPERM;
1364
1365         case RIO_MESG:
1366                 if (su)
1367                         p->RIONoMessage = 0;
1368                 return su ? 0 : -EPERM;
1369
1370         case RIO_WHAT_MESG:
1371                 if (copyout((caddr_t) & p->RIONoMessage, (int) arg, sizeof(p->RIONoMessage)) == COPYFAIL) {
1372                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n");
1373                         p->RIOError.Error = COPYOUT_FAILED;
1374                         return -EFAULT;
1375                 }
1376                 return 0;
1377
1378         case RIO_MEM_DUMP:
1379                 if (copyin((int) arg, (caddr_t) & SubCmd, sizeof(struct SubCmdStruct)) == COPYFAIL) {
1380                         p->RIOError.Error = COPYIN_FAILED;
1381                         return -EFAULT;
1382                 }
1383                 rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP host %d rup %d addr %x\n", SubCmd.Host, SubCmd.Rup, SubCmd.Addr);
1384
1385                 if (SubCmd.Rup >= MAX_RUP + LINKS_PER_UNIT) {
1386                         p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
1387                         return -EINVAL;
1388                 }
1389
1390                 if (SubCmd.Host >= p->RIONumHosts) {
1391                         p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
1392                         return -EINVAL;
1393                 }
1394
1395                 port = p->RIOHosts[SubCmd.Host].UnixRups[SubCmd.Rup].BaseSysPort;
1396
1397                 PortP = p->RIOPortp[port];
1398
1399                 rio_spin_lock_irqsave(&PortP->portSem, flags);
1400
1401                 if (RIOPreemptiveCmd(p, PortP, MEMDUMP) == RIO_FAIL) {
1402                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n");
1403                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1404                         return -EBUSY;
1405                 } else
1406                         PortP->State |= RIO_BUSY;
1407
1408                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1409                 if (copyout((caddr_t) p->RIOMemDump, (int) arg, MEMDUMP_SIZE) == COPYFAIL) {
1410                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n");
1411                         p->RIOError.Error = COPYOUT_FAILED;
1412                         return -EFAULT;
1413                 }
1414                 return 0;
1415
1416         case RIO_TICK:
1417                 if ((int) arg < 0 || (int) arg >= p->RIONumHosts)
1418                         return -EINVAL;
1419                 rio_dprintk(RIO_DEBUG_CTRL, "Set interrupt for host %d\n", (int) arg);
1420                 WBYTE(p->RIOHosts[(int) arg].SetInt, 0xff);
1421                 return 0;
1422
1423         case RIO_TOCK:
1424                 if ((int) arg < 0 || (int) arg >= p->RIONumHosts)
1425                         return -EINVAL;
1426                 rio_dprintk(RIO_DEBUG_CTRL, "Clear interrupt for host %d\n", (int) arg);
1427                 WBYTE((p->RIOHosts[(int) arg].ResetInt), 0xff);
1428                 return 0;
1429
1430         case RIO_READ_CHECK:
1431                 /* Check reads for pkts with data[0] the same */
1432                 p->RIOReadCheck = !p->RIOReadCheck;
1433                 if (copyout((caddr_t) & p->RIOReadCheck, (int) arg, sizeof(uint)) == COPYFAIL) {
1434                         p->RIOError.Error = COPYOUT_FAILED;
1435                         return -EFAULT;
1436                 }
1437                 return 0;
1438
1439         case RIO_READ_REGISTER:
1440                 if (copyin((int) arg, (caddr_t) & SubCmd, sizeof(struct SubCmdStruct)) == COPYFAIL) {
1441                         p->RIOError.Error = COPYIN_FAILED;
1442                         return -EFAULT;
1443                 }
1444                 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);
1445
1446                 if (SubCmd.Port > 511) {
1447                         rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", SubCmd.Port);
1448                         p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
1449                         return -EINVAL;
1450                 }
1451
1452                 if (SubCmd.Rup >= MAX_RUP + LINKS_PER_UNIT) {
1453                         p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
1454                         return -EINVAL;
1455                 }
1456
1457                 if (SubCmd.Host >= p->RIONumHosts) {
1458                         p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
1459                         return -EINVAL;
1460                 }
1461
1462                 port = p->RIOHosts[SubCmd.Host].UnixRups[SubCmd.Rup].BaseSysPort + SubCmd.Port;
1463                 PortP = p->RIOPortp[port];
1464
1465                 rio_spin_lock_irqsave(&PortP->portSem, flags);
1466
1467                 if (RIOPreemptiveCmd(p, PortP, READ_REGISTER) == RIO_FAIL) {
1468                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n");
1469                         rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1470                         return -EBUSY;
1471                 } else
1472                         PortP->State |= RIO_BUSY;
1473
1474                 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1475                 if (copyout((caddr_t) & p->CdRegister, (int) arg, sizeof(uint)) == COPYFAIL) {
1476                         rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n");
1477                         p->RIOError.Error = COPYOUT_FAILED;
1478                         return -EFAULT;
1479                 }
1480                 return 0;
1481                 /*
1482                  ** rio_make_dev: given port number (0-511) ORed with port type
1483                  ** (RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT) return dev_t
1484                  ** value to pass to mknod to create the correct device node.
1485                  */
1486         case RIO_MAKE_DEV:
1487                 {
1488                         uint port = (uint) arg & RIO_MODEM_MASK;
1489
1490                         switch ((uint) arg & RIO_DEV_MASK) {
1491                         case RIO_DEV_DIRECT:
1492                                 arg = (caddr_t) drv_makedev(MAJOR(dev), port);
1493                                 rio_dprintk(RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n", port, (int) arg);
1494                                 return (int) arg;
1495                         case RIO_DEV_MODEM:
1496                                 arg = (caddr_t) drv_makedev(MAJOR(dev), (port | RIO_MODEM_BIT));
1497                                 rio_dprintk(RIO_DEBUG_CTRL, "Makedev modem 0x%x is 0x%x\n", port, (int) arg);
1498                                 return (int) arg;
1499                         case RIO_DEV_XPRINT:
1500                                 arg = (caddr_t) drv_makedev(MAJOR(dev), port);
1501                                 rio_dprintk(RIO_DEBUG_CTRL, "Makedev printer 0x%x is 0x%x\n", port, (int) arg);
1502                                 return (int) arg;
1503                         }
1504                         rio_dprintk(RIO_DEBUG_CTRL, "MAKE Device is called\n");
1505                         return -EINVAL;
1506                 }
1507                 /*
1508                  ** rio_minor: given a dev_t from a stat() call, return
1509                  ** the port number (0-511) ORed with the port type
1510                  ** ( RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT )
1511                  */
1512         case RIO_MINOR:
1513                 {
1514                         dev_t dv;
1515                         int mino;
1516
1517                         dv = (dev_t) ((int) arg);
1518                         mino = RIO_UNMODEM(dv);
1519
1520                         if (RIO_ISMODEM(dv)) {
1521                                 rio_dprintk(RIO_DEBUG_CTRL, "Minor for device 0x%x: modem %d\n", dv, mino);
1522                                 arg = (caddr_t) (mino | RIO_DEV_MODEM);
1523                         } else {
1524                                 rio_dprintk(RIO_DEBUG_CTRL, "Minor for device 0x%x: direct %d\n", dv, mino);
1525                                 arg = (caddr_t) (mino | RIO_DEV_DIRECT);
1526                         }
1527                         return (int) arg;
1528                 }
1529         }
1530         rio_dprintk(RIO_DEBUG_CTRL, "INVALID DAEMON IOCTL 0x%x\n", cmd);
1531         p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
1532
1533         func_exit();
1534         return -EINVAL;
1535 }
1536
1537 /*
1538 ** Pre-emptive commands go on RUPs and are only one byte long.
1539 */
1540 int RIOPreemptiveCmd(p, PortP, Cmd)
1541 struct rio_info *p;
1542 struct Port *PortP;
1543 uchar Cmd;
1544 {
1545         struct CmdBlk *CmdBlkP;
1546         struct PktCmd_M *PktCmdP;
1547         int Ret;
1548         ushort rup;
1549         int port;
1550
1551         if (PortP->State & RIO_DELETED) {
1552                 rio_dprintk(RIO_DEBUG_CTRL, "Preemptive command to deleted RTA ignored\n");
1553                 return RIO_FAIL;
1554         }
1555
1556         if (((int) ((char) PortP->InUse) == -1) || !(CmdBlkP = RIOGetCmdBlk())) {
1557                 rio_dprintk(RIO_DEBUG_CTRL, "Cannot allocate command block for command %d on port %d\n", Cmd, PortP->PortNum);
1558                 return RIO_FAIL;
1559         }
1560
1561         rio_dprintk(RIO_DEBUG_CTRL, "Command blk 0x%x - InUse now %d\n", (int) CmdBlkP, PortP->InUse);
1562
1563         PktCmdP = (struct PktCmd_M *) &CmdBlkP->Packet.data[0];
1564
1565         CmdBlkP->Packet.src_unit = 0;
1566         if (PortP->SecondBlock)
1567                 rup = PortP->ID2;
1568         else
1569                 rup = PortP->RupNum;
1570         CmdBlkP->Packet.dest_unit = rup;
1571         CmdBlkP->Packet.src_port = COMMAND_RUP;
1572         CmdBlkP->Packet.dest_port = COMMAND_RUP;
1573         CmdBlkP->Packet.len = PKT_CMD_BIT | 2;
1574         CmdBlkP->PostFuncP = RIOUnUse;
1575         CmdBlkP->PostArg = (int) PortP;
1576         PktCmdP->Command = Cmd;
1577         port = PortP->HostPort % (ushort) PORTS_PER_RTA;
1578         /*
1579          ** Index ports 8-15 for 2nd block of 16 port RTA.
1580          */
1581         if (PortP->SecondBlock)
1582                 port += (ushort) PORTS_PER_RTA;
1583         PktCmdP->PhbNum = port;
1584
1585         switch (Cmd) {
1586         case MEMDUMP:
1587                 rio_dprintk(RIO_DEBUG_CTRL, "Queue MEMDUMP command blk 0x%x (addr 0x%x)\n", (int) CmdBlkP, (int) SubCmd.Addr);
1588                 PktCmdP->SubCommand = MEMDUMP;
1589                 PktCmdP->SubAddr = SubCmd.Addr;
1590                 break;
1591         case FCLOSE:
1592                 rio_dprintk(RIO_DEBUG_CTRL, "Queue FCLOSE command blk 0x%x\n", (int) CmdBlkP);
1593                 break;
1594         case READ_REGISTER:
1595                 rio_dprintk(RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) command blk 0x%x\n", (int) SubCmd.Addr, (int) CmdBlkP);
1596                 PktCmdP->SubCommand = READ_REGISTER;
1597                 PktCmdP->SubAddr = SubCmd.Addr;
1598                 break;
1599         case RESUME:
1600                 rio_dprintk(RIO_DEBUG_CTRL, "Queue RESUME command blk 0x%x\n", (int) CmdBlkP);
1601                 break;
1602         case RFLUSH:
1603                 rio_dprintk(RIO_DEBUG_CTRL, "Queue RFLUSH command blk 0x%x\n", (int) CmdBlkP);
1604                 CmdBlkP->PostFuncP = RIORFlushEnable;
1605                 break;
1606         case SUSPEND:
1607                 rio_dprintk(RIO_DEBUG_CTRL, "Queue SUSPEND command blk 0x%x\n", (int) CmdBlkP);
1608                 break;
1609
1610         case MGET:
1611                 rio_dprintk(RIO_DEBUG_CTRL, "Queue MGET command blk 0x%x\n", (int) CmdBlkP);
1612                 break;
1613
1614         case MSET:
1615         case MBIC:
1616         case MBIS:
1617                 CmdBlkP->Packet.data[4] = (char) PortP->ModemLines;
1618                 rio_dprintk(RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command blk 0x%x\n", (int) CmdBlkP);
1619                 break;
1620
1621         case WFLUSH:
1622                 /*
1623                  ** If we have queued up the maximum number of Write flushes
1624                  ** allowed then we should not bother sending any more to the
1625                  ** RTA.
1626                  */
1627                 if ((int) ((char) PortP->WflushFlag) == (int) -1) {
1628                         rio_dprintk(RIO_DEBUG_CTRL, "Trashed WFLUSH, WflushFlag about to wrap!");
1629                         RIOFreeCmdBlk(CmdBlkP);
1630                         return (RIO_FAIL);
1631                 } else {
1632                         rio_dprintk(RIO_DEBUG_CTRL, "Queue WFLUSH command blk 0x%x\n", (int) CmdBlkP);
1633                         CmdBlkP->PostFuncP = RIOWFlushMark;
1634                 }
1635                 break;
1636         }
1637
1638         PortP->InUse++;
1639
1640         Ret = RIOQueueCmdBlk(PortP->HostP, rup, CmdBlkP);
1641
1642         return Ret;
1643 }