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