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

« back to all changes in this revision

Viewing changes to drivers/char/rio/riotable.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          : riotable.c
24
 
**      SID             : 1.2
25
 
**      Last Modified   : 11/6/98 10:33:47
26
 
**      Retrieved       : 11/6/98 10:33:50
27
 
**
28
 
**  ident @(#)riotable.c        1.2
29
 
**
30
 
** -----------------------------------------------------------------------------
31
 
*/
32
 
 
33
 
#include <linux/module.h>
34
 
#include <linux/slab.h>
35
 
#include <linux/errno.h>
36
 
#include <linux/interrupt.h>
37
 
#include <linux/string.h>
38
 
 
39
 
#include <asm/io.h>
40
 
#include <asm/system.h>
41
 
#include <asm/string.h>
42
 
#include <asm/uaccess.h>
43
 
 
44
 
#include <linux/termios.h>
45
 
#include <linux/serial.h>
46
 
 
47
 
#include <linux/generic_serial.h>
48
 
 
49
 
 
50
 
#include "linux_compat.h"
51
 
#include "rio_linux.h"
52
 
#include "pkt.h"
53
 
#include "daemon.h"
54
 
#include "rio.h"
55
 
#include "riospace.h"
56
 
#include "cmdpkt.h"
57
 
#include "map.h"
58
 
#include "rup.h"
59
 
#include "port.h"
60
 
#include "riodrvr.h"
61
 
#include "rioinfo.h"
62
 
#include "func.h"
63
 
#include "errors.h"
64
 
#include "pci.h"
65
 
 
66
 
#include "parmmap.h"
67
 
#include "unixrup.h"
68
 
#include "board.h"
69
 
#include "host.h"
70
 
#include "phb.h"
71
 
#include "link.h"
72
 
#include "cmdblk.h"
73
 
#include "route.h"
74
 
#include "cirrus.h"
75
 
#include "rioioctl.h"
76
 
#include "param.h"
77
 
#include "protsts.h"
78
 
 
79
 
/*
80
 
** A configuration table has been loaded. It is now up to us
81
 
** to sort it out and use the information contained therein.
82
 
*/
83
 
int RIONewTable(struct rio_info *p)
84
 
{
85
 
        int Host, Host1, Host2, NameIsUnique, Entry, SubEnt;
86
 
        struct Map *MapP;
87
 
        struct Map *HostMapP;
88
 
        struct Host *HostP;
89
 
 
90
 
        char *cptr;
91
 
 
92
 
        /*
93
 
         ** We have been sent a new table to install. We need to break
94
 
         ** it down into little bits and spread it around a bit to see
95
 
         ** what we have got.
96
 
         */
97
 
        /*
98
 
         ** Things to check:
99
 
         ** (things marked 'xx' aren't checked any more!)
100
 
         ** (1) That there are no booted Hosts/RTAs out there.
101
 
         ** (2) That the names are properly formed
102
 
         ** (3) That blank entries really are.
103
 
         ** xx (4)      That hosts mentioned in the table actually exist. xx
104
 
         ** (5) That the IDs are unique (per host).
105
 
         ** (6) That host IDs are zero
106
 
         ** (7) That port numbers are valid
107
 
         ** (8) That port numbers aren't duplicated
108
 
         ** (9) That names aren't duplicated
109
 
         ** xx (10) That hosts that actually exist are mentioned in the table. xx
110
 
         */
111
 
        rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(1)\n");
112
 
        if (p->RIOSystemUp) {   /* (1) */
113
 
                p->RIOError.Error = HOST_HAS_ALREADY_BEEN_BOOTED;
114
 
                return -EBUSY;
115
 
        }
116
 
 
117
 
        p->RIOError.Error = NOTHING_WRONG_AT_ALL;
118
 
        p->RIOError.Entry = -1;
119
 
        p->RIOError.Other = -1;
120
 
 
121
 
        for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) {
122
 
                MapP = &p->RIOConnectTable[Entry];
123
 
                if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) {
124
 
                        rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(2)\n");
125
 
                        cptr = MapP->Name;      /* (2) */
126
 
                        cptr[MAX_NAME_LEN - 1] = '\0';
127
 
                        if (cptr[0] == '\0') {
128
 
                                memcpy(MapP->Name, MapP->RtaUniqueNum ? "RTA    NN" : "HOST NN", 8);
129
 
                                MapP->Name[5] = '0' + Entry / 10;
130
 
                                MapP->Name[6] = '0' + Entry % 10;
131
 
                        }
132
 
                        while (*cptr) {
133
 
                                if (*cptr < ' ' || *cptr > '~') {
134
 
                                        p->RIOError.Error = BAD_CHARACTER_IN_NAME;
135
 
                                        p->RIOError.Entry = Entry;
136
 
                                        return -ENXIO;
137
 
                                }
138
 
                                cptr++;
139
 
                        }
140
 
                }
141
 
 
142
 
                /*
143
 
                 ** If the entry saved was a tentative entry then just forget
144
 
                 ** about it.
145
 
                 */
146
 
                if (MapP->Flags & SLOT_TENTATIVE) {
147
 
                        MapP->HostUniqueNum = 0;
148
 
                        MapP->RtaUniqueNum = 0;
149
 
                        continue;
150
 
                }
151
 
 
152
 
                rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(3)\n");
153
 
                if (!MapP->RtaUniqueNum && !MapP->HostUniqueNum) {      /* (3) */
154
 
                        if (MapP->ID || MapP->SysPort || MapP->Flags) {
155
 
                                rio_dprintk(RIO_DEBUG_TABLE, "%s pretending to be empty but isn't\n", MapP->Name);
156
 
                                p->RIOError.Error = TABLE_ENTRY_ISNT_PROPERLY_NULL;
157
 
                                p->RIOError.Entry = Entry;
158
 
                                return -ENXIO;
159
 
                        }
160
 
                        rio_dprintk(RIO_DEBUG_TABLE, "!RIO: Daemon: test (3) passes\n");
161
 
                        continue;
162
 
                }
163
 
 
164
 
                rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(4)\n");
165
 
                for (Host = 0; Host < p->RIONumHosts; Host++) { /* (4) */
166
 
                        if (p->RIOHosts[Host].UniqueNum == MapP->HostUniqueNum) {
167
 
                                HostP = &p->RIOHosts[Host];
168
 
                                /*
169
 
                                 ** having done the lookup, we don't really want to do
170
 
                                 ** it again, so hang the host number in a safe place
171
 
                                 */
172
 
                                MapP->Topology[0].Unit = Host;
173
 
                                break;
174
 
                        }
175
 
                }
176
 
 
177
 
                if (Host >= p->RIONumHosts) {
178
 
                        rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has unknown host unique number 0x%x\n", MapP->Name, MapP->HostUniqueNum);
179
 
                        MapP->HostUniqueNum = 0;
180
 
                        /* MapP->RtaUniqueNum   = 0; */
181
 
                        /* MapP->ID                     = 0; */
182
 
                        /* MapP->Flags           = 0; */
183
 
                        /* MapP->SysPort                 = 0; */
184
 
                        /* MapP->Name[0]                 = 0; */
185
 
                        continue;
186
 
                }
187
 
 
188
 
                rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(5)\n");
189
 
                if (MapP->RtaUniqueNum) {       /* (5) */
190
 
                        if (!MapP->ID) {
191
 
                                rio_dprintk(RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an ID of zero!\n", MapP->Name);
192
 
                                p->RIOError.Error = ZERO_RTA_ID;
193
 
                                p->RIOError.Entry = Entry;
194
 
                                return -ENXIO;
195
 
                        }
196
 
                        if (MapP->ID > MAX_RUP) {
197
 
                                rio_dprintk(RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an invalid ID %d\n", MapP->Name, MapP->ID);
198
 
                                p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
199
 
                                p->RIOError.Entry = Entry;
200
 
                                return -ENXIO;
201
 
                        }
202
 
                        for (SubEnt = 0; SubEnt < Entry; SubEnt++) {
203
 
                                if (MapP->HostUniqueNum == p->RIOConnectTable[SubEnt].HostUniqueNum && MapP->ID == p->RIOConnectTable[SubEnt].ID) {
204
 
                                        rio_dprintk(RIO_DEBUG_TABLE, "Dupl. ID number allocated to RTA %s and RTA %s\n", MapP->Name, p->RIOConnectTable[SubEnt].Name);
205
 
                                        p->RIOError.Error = DUPLICATED_RTA_ID;
206
 
                                        p->RIOError.Entry = Entry;
207
 
                                        p->RIOError.Other = SubEnt;
208
 
                                        return -ENXIO;
209
 
                                }
210
 
                                /*
211
 
                                 ** If the RtaUniqueNum is the same, it may be looking at both
212
 
                                 ** entries for a 16 port RTA, so check the ids
213
 
                                 */
214
 
                                if ((MapP->RtaUniqueNum == p->RIOConnectTable[SubEnt].RtaUniqueNum)
215
 
                                    && (MapP->ID2 != p->RIOConnectTable[SubEnt].ID)) {
216
 
                                        rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n", MapP->Name);
217
 
                                        rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n", p->RIOConnectTable[SubEnt].Name);
218
 
                                        p->RIOError.Error = DUPLICATE_UNIQUE_NUMBER;
219
 
                                        p->RIOError.Entry = Entry;
220
 
                                        p->RIOError.Other = SubEnt;
221
 
                                        return -ENXIO;
222
 
                                }
223
 
                        }
224
 
                        rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(7a)\n");
225
 
                        /* (7a) */
226
 
                        if ((MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA)) {
227
 
                                rio_dprintk(RIO_DEBUG_TABLE, "TTY Port number %d-RTA %s is not a multiple of %d!\n", (int) MapP->SysPort, MapP->Name, PORTS_PER_RTA);
228
 
                                p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
229
 
                                p->RIOError.Entry = Entry;
230
 
                                return -ENXIO;
231
 
                        }
232
 
                        rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(7b)\n");
233
 
                        /* (7b) */
234
 
                        if ((MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS)) {
235
 
                                rio_dprintk(RIO_DEBUG_TABLE, "TTY Port number %d for RTA %s is too big\n", (int) MapP->SysPort, MapP->Name);
236
 
                                p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
237
 
                                p->RIOError.Entry = Entry;
238
 
                                return -ENXIO;
239
 
                        }
240
 
                        for (SubEnt = 0; SubEnt < Entry; SubEnt++) {
241
 
                                if (p->RIOConnectTable[SubEnt].Flags & RTA16_SECOND_SLOT)
242
 
                                        continue;
243
 
                                if (p->RIOConnectTable[SubEnt].RtaUniqueNum) {
244
 
                                        rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(8)\n");
245
 
                                        /* (8) */
246
 
                                        if ((MapP->SysPort != NO_PORT) && (MapP->SysPort == p->RIOConnectTable[SubEnt].SysPort)) {
247
 
                                                rio_dprintk(RIO_DEBUG_TABLE, "RTA %s:same TTY port # as RTA %s (%d)\n", MapP->Name, p->RIOConnectTable[SubEnt].Name, (int) MapP->SysPort);
248
 
                                                p->RIOError.Error = TTY_NUMBER_IN_USE;
249
 
                                                p->RIOError.Entry = Entry;
250
 
                                                p->RIOError.Other = SubEnt;
251
 
                                                return -ENXIO;
252
 
                                        }
253
 
                                        rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(9)\n");
254
 
                                        if (strcmp(MapP->Name, p->RIOConnectTable[SubEnt].Name) == 0 && !(MapP->Flags & RTA16_SECOND_SLOT)) {   /* (9) */
255
 
                                                rio_dprintk(RIO_DEBUG_TABLE, "RTA name %s used twice\n", MapP->Name);
256
 
                                                p->RIOError.Error = NAME_USED_TWICE;
257
 
                                                p->RIOError.Entry = Entry;
258
 
                                                p->RIOError.Other = SubEnt;
259
 
                                                return -ENXIO;
260
 
                                        }
261
 
                                }
262
 
                        }
263
 
                } else {        /* (6) */
264
 
                        rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(6)\n");
265
 
                        if (MapP->ID) {
266
 
                                rio_dprintk(RIO_DEBUG_TABLE, "RIO:HOST %s has been allocated ID that isn't zero!\n", MapP->Name);
267
 
                                p->RIOError.Error = HOST_ID_NOT_ZERO;
268
 
                                p->RIOError.Entry = Entry;
269
 
                                return -ENXIO;
270
 
                        }
271
 
                        if (MapP->SysPort != NO_PORT) {
272
 
                                rio_dprintk(RIO_DEBUG_TABLE, "RIO: HOST %s has been allocated port numbers!\n", MapP->Name);
273
 
                                p->RIOError.Error = HOST_SYSPORT_BAD;
274
 
                                p->RIOError.Entry = Entry;
275
 
                                return -ENXIO;
276
 
                        }
277
 
                }
278
 
        }
279
 
 
280
 
        /*
281
 
         ** wow! if we get here then it's a goody!
282
 
         */
283
 
 
284
 
        /*
285
 
         ** Zero the (old) entries for each host...
286
 
         */
287
 
        for (Host = 0; Host < RIO_HOSTS; Host++) {
288
 
                for (Entry = 0; Entry < MAX_RUP; Entry++) {
289
 
                        memset(&p->RIOHosts[Host].Mapping[Entry], 0, sizeof(struct Map));
290
 
                }
291
 
                memset(&p->RIOHosts[Host].Name[0], 0, sizeof(p->RIOHosts[Host].Name));
292
 
        }
293
 
 
294
 
        /*
295
 
         ** Copy in the new table entries
296
 
         */
297
 
        for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) {
298
 
                rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: Copy table for Host entry %d\n", Entry);
299
 
                MapP = &p->RIOConnectTable[Entry];
300
 
 
301
 
                /*
302
 
                 ** Now, if it is an empty slot ignore it!
303
 
                 */
304
 
                if (MapP->HostUniqueNum == 0)
305
 
                        continue;
306
 
 
307
 
                /*
308
 
                 ** we saved the host number earlier, so grab it back
309
 
                 */
310
 
                HostP = &p->RIOHosts[MapP->Topology[0].Unit];
311
 
 
312
 
                /*
313
 
                 ** If it is a host, then we only need to fill in the name field.
314
 
                 */
315
 
                if (MapP->ID == 0) {
316
 
                        rio_dprintk(RIO_DEBUG_TABLE, "Host entry found. Name %s\n", MapP->Name);
317
 
                        memcpy(HostP->Name, MapP->Name, MAX_NAME_LEN);
318
 
                        continue;
319
 
                }
320
 
 
321
 
                /*
322
 
                 ** Its an RTA entry, so fill in the host mapping entries for it
323
 
                 ** and the port mapping entries. Notice that entry zero is for
324
 
                 ** ID one.
325
 
                 */
326
 
                HostMapP = &HostP->Mapping[MapP->ID - 1];
327
 
 
328
 
                if (MapP->Flags & SLOT_IN_USE) {
329
 
                        rio_dprintk(RIO_DEBUG_TABLE, "Rta entry found. Name %s\n", MapP->Name);
330
 
                        /*
331
 
                         ** structure assign, then sort out the bits we shouldn't have done
332
 
                         */
333
 
                        *HostMapP = *MapP;
334
 
 
335
 
                        HostMapP->Flags = SLOT_IN_USE;
336
 
                        if (MapP->Flags & RTA16_SECOND_SLOT)
337
 
                                HostMapP->Flags |= RTA16_SECOND_SLOT;
338
 
 
339
 
                        RIOReMapPorts(p, HostP, HostMapP);
340
 
                } else {
341
 
                        rio_dprintk(RIO_DEBUG_TABLE, "TENTATIVE Rta entry found. Name %s\n", MapP->Name);
342
 
                }
343
 
        }
344
 
 
345
 
        for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) {
346
 
                p->RIOSavedTable[Entry] = p->RIOConnectTable[Entry];
347
 
        }
348
 
 
349
 
        for (Host = 0; Host < p->RIONumHosts; Host++) {
350
 
                for (SubEnt = 0; SubEnt < LINKS_PER_UNIT; SubEnt++) {
351
 
                        p->RIOHosts[Host].Topology[SubEnt].Unit = ROUTE_DISCONNECT;
352
 
                        p->RIOHosts[Host].Topology[SubEnt].Link = NO_LINK;
353
 
                }
354
 
                for (Entry = 0; Entry < MAX_RUP; Entry++) {
355
 
                        for (SubEnt = 0; SubEnt < LINKS_PER_UNIT; SubEnt++) {
356
 
                                p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Unit = ROUTE_DISCONNECT;
357
 
                                p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Link = NO_LINK;
358
 
                        }
359
 
                }
360
 
                if (!p->RIOHosts[Host].Name[0]) {
361
 
                        memcpy(p->RIOHosts[Host].Name, "HOST 1", 7);
362
 
                        p->RIOHosts[Host].Name[5] += Host;
363
 
                }
364
 
                /*
365
 
                 ** Check that default name assigned is unique.
366
 
                 */
367
 
                Host1 = Host;
368
 
                NameIsUnique = 0;
369
 
                while (!NameIsUnique) {
370
 
                        NameIsUnique = 1;
371
 
                        for (Host2 = 0; Host2 < p->RIONumHosts; Host2++) {
372
 
                                if (Host2 == Host)
373
 
                                        continue;
374
 
                                if (strcmp(p->RIOHosts[Host].Name, p->RIOHosts[Host2].Name)
375
 
                                    == 0) {
376
 
                                        NameIsUnique = 0;
377
 
                                        Host1++;
378
 
                                        if (Host1 >= p->RIONumHosts)
379
 
                                                Host1 = 0;
380
 
                                        p->RIOHosts[Host].Name[5] = '1' + Host1;
381
 
                                }
382
 
                        }
383
 
                }
384
 
                /*
385
 
                 ** Rename host if name already used.
386
 
                 */
387
 
                if (Host1 != Host) {
388
 
                        rio_dprintk(RIO_DEBUG_TABLE, "Default name %s already used\n", p->RIOHosts[Host].Name);
389
 
                        memcpy(p->RIOHosts[Host].Name, "HOST 1", 7);
390
 
                        p->RIOHosts[Host].Name[5] += Host1;
391
 
                }
392
 
                rio_dprintk(RIO_DEBUG_TABLE, "Assigning default name %s\n", p->RIOHosts[Host].Name);
393
 
        }
394
 
        return 0;
395
 
}
396
 
 
397
 
/*
398
 
** User process needs the config table - build it from first
399
 
** principles.
400
 
**
401
 
*       FIXME: SMP locking
402
 
*/
403
 
int RIOApel(struct rio_info *p)
404
 
{
405
 
        int Host;
406
 
        int link;
407
 
        int Rup;
408
 
        int Next = 0;
409
 
        struct Map *MapP;
410
 
        struct Host *HostP;
411
 
        unsigned long flags;
412
 
 
413
 
        rio_dprintk(RIO_DEBUG_TABLE, "Generating a table to return to config.rio\n");
414
 
 
415
 
        memset(&p->RIOConnectTable[0], 0, sizeof(struct Map) * TOTAL_MAP_ENTRIES);
416
 
 
417
 
        for (Host = 0; Host < RIO_HOSTS; Host++) {
418
 
                rio_dprintk(RIO_DEBUG_TABLE, "Processing host %d\n", Host);
419
 
                HostP = &p->RIOHosts[Host];
420
 
                rio_spin_lock_irqsave(&HostP->HostLock, flags);
421
 
 
422
 
                MapP = &p->RIOConnectTable[Next++];
423
 
                MapP->HostUniqueNum = HostP->UniqueNum;
424
 
                if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
425
 
                        rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
426
 
                        continue;
427
 
                }
428
 
                MapP->RtaUniqueNum = 0;
429
 
                MapP->ID = 0;
430
 
                MapP->Flags = SLOT_IN_USE;
431
 
                MapP->SysPort = NO_PORT;
432
 
                for (link = 0; link < LINKS_PER_UNIT; link++)
433
 
                        MapP->Topology[link] = HostP->Topology[link];
434
 
                memcpy(MapP->Name, HostP->Name, MAX_NAME_LEN);
435
 
                for (Rup = 0; Rup < MAX_RUP; Rup++) {
436
 
                        if (HostP->Mapping[Rup].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) {
437
 
                                p->RIOConnectTable[Next] = HostP->Mapping[Rup];
438
 
                                if (HostP->Mapping[Rup].Flags & SLOT_IN_USE)
439
 
                                        p->RIOConnectTable[Next].Flags |= SLOT_IN_USE;
440
 
                                if (HostP->Mapping[Rup].Flags & SLOT_TENTATIVE)
441
 
                                        p->RIOConnectTable[Next].Flags |= SLOT_TENTATIVE;
442
 
                                if (HostP->Mapping[Rup].Flags & RTA16_SECOND_SLOT)
443
 
                                        p->RIOConnectTable[Next].Flags |= RTA16_SECOND_SLOT;
444
 
                                Next++;
445
 
                        }
446
 
                }
447
 
                rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
448
 
        }
449
 
        return 0;
450
 
}
451
 
 
452
 
/*
453
 
** config.rio has taken a dislike to one of the gross maps entries.
454
 
** if the entry is suitably inactive, then we can gob on it and remove
455
 
** it from the table.
456
 
*/
457
 
int RIODeleteRta(struct rio_info *p, struct Map *MapP)
458
 
{
459
 
        int host, entry, port, link;
460
 
        int SysPort;
461
 
        struct Host *HostP;
462
 
        struct Map *HostMapP;
463
 
        struct Port *PortP;
464
 
        int work_done = 0;
465
 
        unsigned long lock_flags, sem_flags;
466
 
 
467
 
        rio_dprintk(RIO_DEBUG_TABLE, "Delete entry on host %x, rta %x\n", MapP->HostUniqueNum, MapP->RtaUniqueNum);
468
 
 
469
 
        for (host = 0; host < p->RIONumHosts; host++) {
470
 
                HostP = &p->RIOHosts[host];
471
 
 
472
 
                rio_spin_lock_irqsave(&HostP->HostLock, lock_flags);
473
 
 
474
 
                if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
475
 
                        rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags);
476
 
                        continue;
477
 
                }
478
 
 
479
 
                for (entry = 0; entry < MAX_RUP; entry++) {
480
 
                        if (MapP->RtaUniqueNum == HostP->Mapping[entry].RtaUniqueNum) {
481
 
                                HostMapP = &HostP->Mapping[entry];
482
 
                                rio_dprintk(RIO_DEBUG_TABLE, "Found entry offset %d on host %s\n", entry, HostP->Name);
483
 
 
484
 
                                /*
485
 
                                 ** Check all four links of the unit are disconnected
486
 
                                 */
487
 
                                for (link = 0; link < LINKS_PER_UNIT; link++) {
488
 
                                        if (HostMapP->Topology[link].Unit != ROUTE_DISCONNECT) {
489
 
                                                rio_dprintk(RIO_DEBUG_TABLE, "Entry is in use and cannot be deleted!\n");
490
 
                                                p->RIOError.Error = UNIT_IS_IN_USE;
491
 
                                                rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags);
492
 
                                                return -EBUSY;
493
 
                                        }
494
 
                                }
495
 
                                /*
496
 
                                 ** Slot has been allocated, BUT not booted/routed/
497
 
                                 ** connected/selected or anything else-ed
498
 
                                 */
499
 
                                SysPort = HostMapP->SysPort;
500
 
 
501
 
                                if (SysPort != NO_PORT) {
502
 
                                        for (port = SysPort; port < SysPort + PORTS_PER_RTA; port++) {
503
 
                                                PortP = p->RIOPortp[port];
504
 
                                                rio_dprintk(RIO_DEBUG_TABLE, "Unmap port\n");
505
 
 
506
 
                                                rio_spin_lock_irqsave(&PortP->portSem, sem_flags);
507
 
 
508
 
                                                PortP->Mapped = 0;
509
 
 
510
 
                                                if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) {
511
 
 
512
 
                                                        rio_dprintk(RIO_DEBUG_TABLE, "Gob on port\n");
513
 
                                                        PortP->TxBufferIn = PortP->TxBufferOut = 0;
514
 
                                                        /* What should I do 
515
 
                                                           wakeup( &PortP->TxBufferIn );
516
 
                                                           wakeup( &PortP->TxBufferOut);
517
 
                                                         */
518
 
                                                        PortP->InUse = NOT_INUSE;
519
 
                                                        /* What should I do 
520
 
                                                           wakeup( &PortP->InUse );
521
 
                                                           signal(PortP->TtyP->t_pgrp,SIGKILL);
522
 
                                                           ttyflush(PortP->TtyP,(FREAD|FWRITE));
523
 
                                                         */
524
 
                                                        PortP->State |= RIO_CLOSING | RIO_DELETED;
525
 
                                                }
526
 
 
527
 
                                                /*
528
 
                                                 ** For the second slot of a 16 port RTA, the
529
 
                                                 ** driver needs to reset the changes made to
530
 
                                                 ** the phb to port mappings in RIORouteRup.
531
 
                                                 */
532
 
                                                if (PortP->SecondBlock) {
533
 
                                                        u16 dest_unit = HostMapP->ID;
534
 
                                                        u16 dest_port = port - SysPort;
535
 
                                                        u16 __iomem *TxPktP;
536
 
                                                        struct PKT __iomem *Pkt;
537
 
 
538
 
                                                        for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) {
539
 
                                                                /*
540
 
                                                                 ** *TxPktP is the pointer to the
541
 
                                                                 ** transmit packet on the host card.
542
 
                                                                 ** This needs to be translated into
543
 
                                                                 ** a 32 bit pointer so it can be
544
 
                                                                 ** accessed from the driver.
545
 
                                                                 */
546
 
                                                                Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&*TxPktP));
547
 
                                                                rio_dprintk(RIO_DEBUG_TABLE, "Tx packet (%x) destination: Old %x:%x New %x:%x\n", readw(TxPktP), readb(&Pkt->dest_unit), readb(&Pkt->dest_port), dest_unit, dest_port);
548
 
                                                                writew(dest_unit, &Pkt->dest_unit);
549
 
                                                                writew(dest_port, &Pkt->dest_port);
550
 
                                                        }
551
 
                                                        rio_dprintk(RIO_DEBUG_TABLE, "Port %d phb destination: Old %x:%x New %x:%x\n", port, readb(&PortP->PhbP->destination) & 0xff, (readb(&PortP->PhbP->destination) >> 8) & 0xff, dest_unit, dest_port);
552
 
                                                        writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination);
553
 
                                                }
554
 
                                                rio_spin_unlock_irqrestore(&PortP->portSem, sem_flags);
555
 
                                        }
556
 
                                }
557
 
                                rio_dprintk(RIO_DEBUG_TABLE, "Entry nulled.\n");
558
 
                                memset(HostMapP, 0, sizeof(struct Map));
559
 
                                work_done++;
560
 
                        }
561
 
                }
562
 
                rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags);
563
 
        }
564
 
 
565
 
        /* XXXXX lock me up */
566
 
        for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) {
567
 
                if (p->RIOSavedTable[entry].RtaUniqueNum == MapP->RtaUniqueNum) {
568
 
                        memset(&p->RIOSavedTable[entry], 0, sizeof(struct Map));
569
 
                        work_done++;
570
 
                }
571
 
                if (p->RIOConnectTable[entry].RtaUniqueNum == MapP->RtaUniqueNum) {
572
 
                        memset(&p->RIOConnectTable[entry], 0, sizeof(struct Map));
573
 
                        work_done++;
574
 
                }
575
 
        }
576
 
        if (work_done)
577
 
                return 0;
578
 
 
579
 
        rio_dprintk(RIO_DEBUG_TABLE, "Couldn't find entry to be deleted\n");
580
 
        p->RIOError.Error = COULDNT_FIND_ENTRY;
581
 
        return -ENXIO;
582
 
}
583
 
 
584
 
int RIOAssignRta(struct rio_info *p, struct Map *MapP)
585
 
{
586
 
        int host;
587
 
        struct Map *HostMapP;
588
 
        char *sptr;
589
 
        int link;
590
 
 
591
 
 
592
 
        rio_dprintk(RIO_DEBUG_TABLE, "Assign entry on host %x, rta %x, ID %d, Sysport %d\n", MapP->HostUniqueNum, MapP->RtaUniqueNum, MapP->ID, (int) MapP->SysPort);
593
 
 
594
 
        if ((MapP->ID != (u16) - 1) && ((int) MapP->ID < (int) 1 || (int) MapP->ID > MAX_RUP)) {
595
 
                rio_dprintk(RIO_DEBUG_TABLE, "Bad ID in map entry!\n");
596
 
                p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
597
 
                return -EINVAL;
598
 
        }
599
 
        if (MapP->RtaUniqueNum == 0) {
600
 
                rio_dprintk(RIO_DEBUG_TABLE, "Rta Unique number zero!\n");
601
 
                p->RIOError.Error = RTA_UNIQUE_NUMBER_ZERO;
602
 
                return -EINVAL;
603
 
        }
604
 
        if ((MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA)) {
605
 
                rio_dprintk(RIO_DEBUG_TABLE, "Port %d not multiple of %d!\n", (int) MapP->SysPort, PORTS_PER_RTA);
606
 
                p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
607
 
                return -EINVAL;
608
 
        }
609
 
        if ((MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS)) {
610
 
                rio_dprintk(RIO_DEBUG_TABLE, "Port %d not valid!\n", (int) MapP->SysPort);
611
 
                p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
612
 
                return -EINVAL;
613
 
        }
614
 
 
615
 
        /*
616
 
         ** Copy the name across to the map entry.
617
 
         */
618
 
        MapP->Name[MAX_NAME_LEN - 1] = '\0';
619
 
        sptr = MapP->Name;
620
 
        while (*sptr) {
621
 
                if (*sptr < ' ' || *sptr > '~') {
622
 
                        rio_dprintk(RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n");
623
 
                        p->RIOError.Error = BAD_CHARACTER_IN_NAME;
624
 
                        return -EINVAL;
625
 
                }
626
 
                sptr++;
627
 
        }
628
 
 
629
 
        for (host = 0; host < p->RIONumHosts; host++) {
630
 
                if (MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum) {
631
 
                        if ((p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING) {
632
 
                                p->RIOError.Error = HOST_NOT_RUNNING;
633
 
                                return -ENXIO;
634
 
                        }
635
 
 
636
 
                        /*
637
 
                         ** Now we have a host we need to allocate an ID
638
 
                         ** if the entry does not already have one.
639
 
                         */
640
 
                        if (MapP->ID == (u16) - 1) {
641
 
                                int nNewID;
642
 
 
643
 
                                rio_dprintk(RIO_DEBUG_TABLE, "Attempting to get a new ID for rta \"%s\"\n", MapP->Name);
644
 
                                /*
645
 
                                 ** The idea here is to allow RTA's to be assigned
646
 
                                 ** before they actually appear on the network.
647
 
                                 ** This allows the addition of RTA's without having
648
 
                                 ** to plug them in.
649
 
                                 ** What we do is:
650
 
                                 **  - Find a free ID and allocate it to the RTA.
651
 
                                 **  - If this map entry is the second half of a
652
 
                                 **    16 port entry then find the other half and
653
 
                                 **    make sure the 2 cross reference each other.
654
 
                                 */
655
 
                                if (RIOFindFreeID(p, &p->RIOHosts[host], &nNewID, NULL) != 0) {
656
 
                                        p->RIOError.Error = COULDNT_FIND_ENTRY;
657
 
                                        return -EBUSY;
658
 
                                }
659
 
                                MapP->ID = (u16) nNewID + 1;
660
 
                                rio_dprintk(RIO_DEBUG_TABLE, "Allocated ID %d for this new RTA.\n", MapP->ID);
661
 
                                HostMapP = &p->RIOHosts[host].Mapping[nNewID];
662
 
                                HostMapP->RtaUniqueNum = MapP->RtaUniqueNum;
663
 
                                HostMapP->HostUniqueNum = MapP->HostUniqueNum;
664
 
                                HostMapP->ID = MapP->ID;
665
 
                                for (link = 0; link < LINKS_PER_UNIT; link++) {
666
 
                                        HostMapP->Topology[link].Unit = ROUTE_DISCONNECT;
667
 
                                        HostMapP->Topology[link].Link = NO_LINK;
668
 
                                }
669
 
                                if (MapP->Flags & RTA16_SECOND_SLOT) {
670
 
                                        int unit;
671
 
 
672
 
                                        for (unit = 0; unit < MAX_RUP; unit++)
673
 
                                                if (p->RIOHosts[host].Mapping[unit].RtaUniqueNum == MapP->RtaUniqueNum)
674
 
                                                        break;
675
 
                                        if (unit == MAX_RUP) {
676
 
                                                p->RIOError.Error = COULDNT_FIND_ENTRY;
677
 
                                                return -EBUSY;
678
 
                                        }
679
 
                                        HostMapP->Flags |= RTA16_SECOND_SLOT;
680
 
                                        HostMapP->ID2 = MapP->ID2 = p->RIOHosts[host].Mapping[unit].ID;
681
 
                                        p->RIOHosts[host].Mapping[unit].ID2 = MapP->ID;
682
 
                                        rio_dprintk(RIO_DEBUG_TABLE, "Cross referenced id %d to ID %d.\n", MapP->ID, p->RIOHosts[host].Mapping[unit].ID);
683
 
                                }
684
 
                        }
685
 
 
686
 
                        HostMapP = &p->RIOHosts[host].Mapping[MapP->ID - 1];
687
 
 
688
 
                        if (HostMapP->Flags & SLOT_IN_USE) {
689
 
                                rio_dprintk(RIO_DEBUG_TABLE, "Map table slot for ID %d is already in use.\n", MapP->ID);
690
 
                                p->RIOError.Error = ID_ALREADY_IN_USE;
691
 
                                return -EBUSY;
692
 
                        }
693
 
 
694
 
                        /*
695
 
                         ** Assign the sys ports and the name, and mark the slot as
696
 
                         ** being in use.
697
 
                         */
698
 
                        HostMapP->SysPort = MapP->SysPort;
699
 
                        if ((MapP->Flags & RTA16_SECOND_SLOT) == 0)
700
 
                                memcpy(HostMapP->Name, MapP->Name, MAX_NAME_LEN);
701
 
                        HostMapP->Flags = SLOT_IN_USE | RTA_BOOTED;
702
 
#ifdef NEED_TO_FIX
703
 
                        RIO_SV_BROADCAST(p->RIOHosts[host].svFlags[MapP->ID - 1]);
704
 
#endif
705
 
                        if (MapP->Flags & RTA16_SECOND_SLOT)
706
 
                                HostMapP->Flags |= RTA16_SECOND_SLOT;
707
 
 
708
 
                        RIOReMapPorts(p, &p->RIOHosts[host], HostMapP);
709
 
                        /*
710
 
                         ** Adjust 2nd block of 8 phbs
711
 
                         */
712
 
                        if (MapP->Flags & RTA16_SECOND_SLOT)
713
 
                                RIOFixPhbs(p, &p->RIOHosts[host], HostMapP->ID - 1);
714
 
 
715
 
                        if (HostMapP->SysPort != NO_PORT) {
716
 
                                if (HostMapP->SysPort < p->RIOFirstPortsBooted)
717
 
                                        p->RIOFirstPortsBooted = HostMapP->SysPort;
718
 
                                if (HostMapP->SysPort > p->RIOLastPortsBooted)
719
 
                                        p->RIOLastPortsBooted = HostMapP->SysPort;
720
 
                        }
721
 
                        if (MapP->Flags & RTA16_SECOND_SLOT)
722
 
                                rio_dprintk(RIO_DEBUG_TABLE, "Second map of RTA %s added to configuration\n", p->RIOHosts[host].Mapping[MapP->ID2 - 1].Name);
723
 
                        else
724
 
                                rio_dprintk(RIO_DEBUG_TABLE, "RTA %s added to configuration\n", MapP->Name);
725
 
                        return 0;
726
 
                }
727
 
        }
728
 
        p->RIOError.Error = UNKNOWN_HOST_NUMBER;
729
 
        rio_dprintk(RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum);
730
 
        return -ENXIO;
731
 
}
732
 
 
733
 
 
734
 
int RIOReMapPorts(struct rio_info *p, struct Host *HostP, struct Map *HostMapP)
735
 
{
736
 
        struct Port *PortP;
737
 
        unsigned int SubEnt;
738
 
        unsigned int HostPort;
739
 
        unsigned int SysPort;
740
 
        u16 RtaType;
741
 
        unsigned long flags;
742
 
 
743
 
        rio_dprintk(RIO_DEBUG_TABLE, "Mapping sysport %d to id %d\n", (int) HostMapP->SysPort, HostMapP->ID);
744
 
 
745
 
        /*
746
 
         ** We need to tell the UnixRups which sysport the rup corresponds to
747
 
         */
748
 
        HostP->UnixRups[HostMapP->ID - 1].BaseSysPort = HostMapP->SysPort;
749
 
 
750
 
        if (HostMapP->SysPort == NO_PORT)
751
 
                return (0);
752
 
 
753
 
        RtaType = GetUnitType(HostMapP->RtaUniqueNum);
754
 
        rio_dprintk(RIO_DEBUG_TABLE, "Mapping sysport %d-%d\n", (int) HostMapP->SysPort, (int) HostMapP->SysPort + PORTS_PER_RTA - 1);
755
 
 
756
 
        /*
757
 
         ** now map each of its eight ports
758
 
         */
759
 
        for (SubEnt = 0; SubEnt < PORTS_PER_RTA; SubEnt++) {
760
 
                rio_dprintk(RIO_DEBUG_TABLE, "subent = %d, HostMapP->SysPort = %d\n", SubEnt, (int) HostMapP->SysPort);
761
 
                SysPort = HostMapP->SysPort + SubEnt;   /* portnumber within system */
762
 
                /* portnumber on host */
763
 
 
764
 
                HostPort = (HostMapP->ID - 1) * PORTS_PER_RTA + SubEnt;
765
 
 
766
 
                rio_dprintk(RIO_DEBUG_TABLE, "c1 p = %p, p->rioPortp = %p\n", p, p->RIOPortp);
767
 
                PortP = p->RIOPortp[SysPort];
768
 
                rio_dprintk(RIO_DEBUG_TABLE, "Map port\n");
769
 
 
770
 
                /*
771
 
                 ** Point at all the real neat data structures
772
 
                 */
773
 
                rio_spin_lock_irqsave(&PortP->portSem, flags);
774
 
                PortP->HostP = HostP;
775
 
                PortP->Caddr = HostP->Caddr;
776
 
 
777
 
                /*
778
 
                 ** The PhbP cannot be filled in yet
779
 
                 ** unless the host has been booted
780
 
                 */
781
 
                if ((HostP->Flags & RUN_STATE) == RC_RUNNING) {
782
 
                        struct PHB __iomem *PhbP = PortP->PhbP = &HostP->PhbP[HostPort];
783
 
                        PortP->TxAdd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_add));
784
 
                        PortP->TxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_start));
785
 
                        PortP->TxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_end));
786
 
                        PortP->RxRemove = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_remove));
787
 
                        PortP->RxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_start));
788
 
                        PortP->RxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_end));
789
 
                } else
790
 
                        PortP->PhbP = NULL;
791
 
 
792
 
                /*
793
 
                 ** port related flags
794
 
                 */
795
 
                PortP->HostPort = HostPort;
796
 
                /*
797
 
                 ** For each part of a 16 port RTA, RupNum is ID - 1.
798
 
                 */
799
 
                PortP->RupNum = HostMapP->ID - 1;
800
 
                if (HostMapP->Flags & RTA16_SECOND_SLOT) {
801
 
                        PortP->ID2 = HostMapP->ID2 - 1;
802
 
                        PortP->SecondBlock = 1;
803
 
                } else {
804
 
                        PortP->ID2 = 0;
805
 
                        PortP->SecondBlock = 0;
806
 
                }
807
 
                PortP->RtaUniqueNum = HostMapP->RtaUniqueNum;
808
 
 
809
 
                /*
810
 
                 ** If the port was already mapped then thats all we need to do.
811
 
                 */
812
 
                if (PortP->Mapped) {
813
 
                        rio_spin_unlock_irqrestore(&PortP->portSem, flags);
814
 
                        continue;
815
 
                } else
816
 
                        HostMapP->Flags &= ~RTA_NEWBOOT;
817
 
 
818
 
                PortP->State = 0;
819
 
                PortP->Config = 0;
820
 
                /*
821
 
                 ** Check out the module type - if it is special (read only etc.)
822
 
                 ** then we need to set flags in the PortP->Config.
823
 
                 ** Note: For 16 port RTA, all ports are of the same type.
824
 
                 */
825
 
                if (RtaType == TYPE_RTA16) {
826
 
                        PortP->Config |= p->RIOModuleTypes[HostP->UnixRups[HostMapP->ID - 1].ModTypes].Flags[SubEnt % PORTS_PER_MODULE];
827
 
                } else {
828
 
                        if (SubEnt < PORTS_PER_MODULE)
829
 
                                PortP->Config |= p->RIOModuleTypes[LONYBLE(HostP->UnixRups[HostMapP->ID - 1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE];
830
 
                        else
831
 
                                PortP->Config |= p->RIOModuleTypes[HINYBLE(HostP->UnixRups[HostMapP->ID - 1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE];
832
 
                }
833
 
 
834
 
                /*
835
 
                 ** more port related flags
836
 
                 */
837
 
                PortP->PortState = 0;
838
 
                PortP->ModemLines = 0;
839
 
                PortP->ModemState = 0;
840
 
                PortP->CookMode = COOK_WELL;
841
 
                PortP->ParamSem = 0;
842
 
                PortP->FlushCmdBodge = 0;
843
 
                PortP->WflushFlag = 0;
844
 
                PortP->MagicFlags = 0;
845
 
                PortP->Lock = 0;
846
 
                PortP->Store = 0;
847
 
                PortP->FirstOpen = 1;
848
 
 
849
 
                /*
850
 
                 ** Buffers 'n things
851
 
                 */
852
 
                PortP->RxDataStart = 0;
853
 
                PortP->Cor2Copy = 0;
854
 
                PortP->Name = &HostMapP->Name[0];
855
 
                PortP->statsGather = 0;
856
 
                PortP->txchars = 0;
857
 
                PortP->rxchars = 0;
858
 
                PortP->opens = 0;
859
 
                PortP->closes = 0;
860
 
                PortP->ioctls = 0;
861
 
                if (PortP->TxRingBuffer)
862
 
                        memset(PortP->TxRingBuffer, 0, p->RIOBufferSize);
863
 
                else if (p->RIOBufferSize) {
864
 
                        PortP->TxRingBuffer = kzalloc(p->RIOBufferSize, GFP_KERNEL);
865
 
                }
866
 
                PortP->TxBufferOut = 0;
867
 
                PortP->TxBufferIn = 0;
868
 
                PortP->Debug = 0;
869
 
                /*
870
 
                 ** LastRxTgl stores the state of the rx toggle bit for this
871
 
                 ** port, to be compared with the state of the next pkt received.
872
 
                 ** If the same, we have received the same rx pkt from the RTA
873
 
                 ** twice. Initialise to a value not equal to PHB_RX_TGL or 0.
874
 
                 */
875
 
                PortP->LastRxTgl = ~(u8) PHB_RX_TGL;
876
 
 
877
 
                /*
878
 
                 ** and mark the port as usable
879
 
                 */
880
 
                PortP->Mapped = 1;
881
 
                rio_spin_unlock_irqrestore(&PortP->portSem, flags);
882
 
        }
883
 
        if (HostMapP->SysPort < p->RIOFirstPortsMapped)
884
 
                p->RIOFirstPortsMapped = HostMapP->SysPort;
885
 
        if (HostMapP->SysPort > p->RIOLastPortsMapped)
886
 
                p->RIOLastPortsMapped = HostMapP->SysPort;
887
 
 
888
 
        return 0;
889
 
}
890
 
 
891
 
int RIOChangeName(struct rio_info *p, struct Map *MapP)
892
 
{
893
 
        int host;
894
 
        struct Map *HostMapP;
895
 
        char *sptr;
896
 
 
897
 
        rio_dprintk(RIO_DEBUG_TABLE, "Change name entry on host %x, rta %x, ID %d, Sysport %d\n", MapP->HostUniqueNum, MapP->RtaUniqueNum, MapP->ID, (int) MapP->SysPort);
898
 
 
899
 
        if (MapP->ID > MAX_RUP) {
900
 
                rio_dprintk(RIO_DEBUG_TABLE, "Bad ID in map entry!\n");
901
 
                p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
902
 
                return -EINVAL;
903
 
        }
904
 
 
905
 
        MapP->Name[MAX_NAME_LEN - 1] = '\0';
906
 
        sptr = MapP->Name;
907
 
 
908
 
        while (*sptr) {
909
 
                if (*sptr < ' ' || *sptr > '~') {
910
 
                        rio_dprintk(RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n");
911
 
                        p->RIOError.Error = BAD_CHARACTER_IN_NAME;
912
 
                        return -EINVAL;
913
 
                }
914
 
                sptr++;
915
 
        }
916
 
 
917
 
        for (host = 0; host < p->RIONumHosts; host++) {
918
 
                if (MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum) {
919
 
                        if ((p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING) {
920
 
                                p->RIOError.Error = HOST_NOT_RUNNING;
921
 
                                return -ENXIO;
922
 
                        }
923
 
                        if (MapP->ID == 0) {
924
 
                                memcpy(p->RIOHosts[host].Name, MapP->Name, MAX_NAME_LEN);
925
 
                                return 0;
926
 
                        }
927
 
 
928
 
                        HostMapP = &p->RIOHosts[host].Mapping[MapP->ID - 1];
929
 
 
930
 
                        if (HostMapP->RtaUniqueNum != MapP->RtaUniqueNum) {
931
 
                                p->RIOError.Error = RTA_NUMBER_WRONG;
932
 
                                return -ENXIO;
933
 
                        }
934
 
                        memcpy(HostMapP->Name, MapP->Name, MAX_NAME_LEN);
935
 
                        return 0;
936
 
                }
937
 
        }
938
 
        p->RIOError.Error = UNKNOWN_HOST_NUMBER;
939
 
        rio_dprintk(RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum);
940
 
        return -ENXIO;
941
 
}