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