~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/staging/generic_serial/rio/rioctrl.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
76
static struct LpbReq LpbReq;
 
77
static struct RupReq RupReq;
 
78
static struct PortReq PortReq;
 
79
static struct HostReq HostReq;  /* oh really?  global?  and no locking? */
 
80
static struct HostDpRam HostDpRam;
 
81
static struct DebugCtrl DebugCtrl;
 
82
static struct Map MapEnt;
 
83
static struct PortSetup PortSetup;
 
84
static struct DownLoad DownLoad;
 
85
static struct SendPack SendPack;
 
86
/* static struct StreamInfo     StreamInfo; */
 
87
/* static char modemtable[RIO_PORTS]; */
 
88
static struct SpecialRupCmd SpecialRupCmd;
 
89
static struct PortParams PortParams;
 
90
static struct portStats portStats;
 
91
 
 
92
static struct SubCmdStruct {
 
93
        ushort Host;
 
94
        ushort Rup;
 
95
        ushort Port;
 
96
        ushort Addr;
 
97
} SubCmd;
 
98
 
 
99
struct PortTty {
 
100
        uint port;
 
101
        struct ttystatics Tty;
 
102
};
 
103
 
 
104
static struct PortTty PortTty;
 
105
typedef 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
*/
 
115
static 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
 
 
125
static 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
 
 
137
int 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
*/
 
1391
int 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
}