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