1/*
2** -----------------------------------------------------------------------------
3**
4**  Perle Specialix driver for Linux
5**  ported from the existing SCO driver source
6**
7 *
8 *  (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
9 *
10 *      This program is free software; you can redistribute it and/or modify
11 *      it under the terms of the GNU General Public License as published by
12 *      the Free Software Foundation; either version 2 of the License, or
13 *      (at your option) any later version.
14 *
15 *      This program is distributed in the hope that it will be useful,
16 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *      GNU General Public License for more details.
19 *
20 *      You should have received a copy of the GNU General Public License
21 *      along with this program; if not, write to the Free Software
22 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23**
24**	Module		: riocmd.c
25**	SID		: 1.2
26**	Last Modified	: 11/6/98 10:33:41
27**	Retrieved	: 11/6/98 10:33:49
28**
29**  ident @(#)riocmd.c	1.2
30**
31** -----------------------------------------------------------------------------
32*/
33#ifdef SCCS_LABELS
34static char *_riocmd_c_sccs_ = "@(#)riocmd.c	1.2";
35#endif
36
37#define __NO_VERSION__
38#include <linux/module.h>
39#include <linux/slab.h>
40#include <linux/errno.h>
41#include <linux/tty.h>
42#include <asm/io.h>
43#include <asm/system.h>
44#include <asm/string.h>
45#include <asm/semaphore.h>
46
47#include <linux/termios.h>
48#include <linux/serial.h>
49
50#include <linux/compatmac.h>
51#include <linux/generic_serial.h>
52
53#include "linux_compat.h"
54#include "rio_linux.h"
55#include "typdef.h"
56#include "pkt.h"
57#include "daemon.h"
58#include "rio.h"
59#include "riospace.h"
60#include "top.h"
61#include "cmdpkt.h"
62#include "map.h"
63#include "riotypes.h"
64#include "rup.h"
65#include "port.h"
66#include "riodrvr.h"
67#include "rioinfo.h"
68#include "func.h"
69#include "errors.h"
70#include "pci.h"
71
72#include "parmmap.h"
73#include "unixrup.h"
74#include "board.h"
75#include "host.h"
76#include "error.h"
77#include "phb.h"
78#include "link.h"
79#include "cmdblk.h"
80#include "route.h"
81#include "control.h"
82#include "cirrus.h"
83
84
85static struct IdentifyRta IdRta;
86static struct KillNeighbour KillUnit;
87
88int
89RIOFoadRta(HostP, MapP)
90struct Host *	HostP;
91struct Map *	MapP;
92{
93	struct CmdBlk *CmdBlkP;
94
95	rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA\n");
96
97	CmdBlkP = RIOGetCmdBlk();
98
99	if ( !CmdBlkP ) {
100		rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: GetCmdBlk failed\n");
101		return ENXIO;
102	}
103
104	CmdBlkP->Packet.dest_unit = MapP->ID;
105	CmdBlkP->Packet.dest_port = BOOT_RUP;
106	CmdBlkP->Packet.src_unit  = 0;
107	CmdBlkP->Packet.src_port  = BOOT_RUP;
108	CmdBlkP->Packet.len	   = 0x84;
109	CmdBlkP->Packet.data[0]   = IFOAD;
110	CmdBlkP->Packet.data[1]   = 0;
111	CmdBlkP->Packet.data[2]   = IFOAD_MAGIC & 0xFF;
112	CmdBlkP->Packet.data[3]   = (IFOAD_MAGIC >> 8) & 0xFF;
113
114	if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
115		rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: Failed to queue foad command\n");
116		return EIO;
117	}
118	return 0;
119}
120
121int
122RIOZombieRta(HostP, MapP)
123struct Host *	HostP;
124struct Map *	MapP;
125{
126	struct CmdBlk *CmdBlkP;
127
128	rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA\n");
129
130	CmdBlkP = RIOGetCmdBlk();
131
132	if ( !CmdBlkP ) {
133		rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: GetCmdBlk failed\n");
134		return ENXIO;
135	}
136
137	CmdBlkP->Packet.dest_unit = MapP->ID;
138	CmdBlkP->Packet.dest_port = BOOT_RUP;
139	CmdBlkP->Packet.src_unit  = 0;
140	CmdBlkP->Packet.src_port  = BOOT_RUP;
141	CmdBlkP->Packet.len	   = 0x84;
142	CmdBlkP->Packet.data[0]   = ZOMBIE;
143	CmdBlkP->Packet.data[1]   = 0;
144	CmdBlkP->Packet.data[2]   = ZOMBIE_MAGIC & 0xFF;
145	CmdBlkP->Packet.data[3]   = (ZOMBIE_MAGIC >> 8) & 0xFF;
146
147	if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
148		rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: Failed to queue zombie command\n");
149		return EIO;
150	}
151	return 0;
152}
153
154int
155RIOCommandRta(p, RtaUnique, func)
156struct rio_info *	p;
157uint RtaUnique;
158int (* func)( struct Host *HostP, struct Map *MapP );
159{
160	uint Host;
161
162	rio_dprintk (RIO_DEBUG_CMD, "Command RTA 0x%x func 0x%x\n", RtaUnique, (int)func);
163
164	if ( !RtaUnique )
165		return(0);
166
167	for ( Host = 0; Host < p->RIONumHosts; Host++ ) {
168		uint Rta;
169		struct Host *HostP = &p->RIOHosts[Host];
170
171		for ( Rta = 0; Rta < RTAS_PER_HOST; Rta++ ) {
172			struct Map *MapP = &HostP->Mapping[Rta];
173
174			if ( MapP->RtaUniqueNum == RtaUnique ) {
175				uint Link;
176
177				/*
178				** now, lets just check we have a route to it...
179				** IF the routing stuff is working, then one of the
180				** topology entries for this unit will have a legit
181				** route *somewhere*. We care not where - if its got
182				** any connections, we can get to it.
183				*/
184				for ( Link = 0; Link < LINKS_PER_UNIT; Link++ ) {
185					if ( MapP->Topology[Link].Unit <= (uchar)MAX_RUP ) {
186						/*
187						** Its worth trying the operation...
188						*/
189						return (*func)( HostP, MapP );
190					}
191				}
192			}
193		}
194	}
195	return ENXIO;
196}
197
198
199int
200RIOIdentifyRta(p, arg)
201struct rio_info *	p;
202caddr_t arg;
203{
204	uint Host;
205
206	if ( copyin( (int)arg, (caddr_t)&IdRta, sizeof(IdRta) ) == COPYFAIL ) {
207		rio_dprintk (RIO_DEBUG_CMD, "RIO_IDENTIFY_RTA copy failed\n");
208		p->RIOError.Error = COPYIN_FAILED;
209		return EFAULT;
210	}
211
212	for ( Host = 0 ; Host < p->RIONumHosts; Host++ ) {
213		uint Rta;
214		struct Host *HostP = &p->RIOHosts[Host];
215
216		for ( Rta = 0; Rta < RTAS_PER_HOST; Rta++ ) {
217			struct Map *MapP = &HostP->Mapping[Rta];
218
219			if ( MapP->RtaUniqueNum == IdRta.RtaUnique ) {
220				uint Link;
221				/*
222				** now, lets just check we have a route to it...
223				** IF the routing stuff is working, then one of the
224				** topology entries for this unit will have a legit
225				** route *somewhere*. We care not where - if its got
226				** any connections, we can get to it.
227				*/
228				for ( Link = 0; Link < LINKS_PER_UNIT; Link++ ) {
229					if ( MapP->Topology[Link].Unit <= (uchar)MAX_RUP ) {
230						/*
231						** Its worth trying the operation...
232						*/
233						struct CmdBlk *CmdBlkP;
234
235						rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA\n");
236
237						CmdBlkP = RIOGetCmdBlk();
238
239						if ( !CmdBlkP ) {
240							rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: GetCmdBlk failed\n");
241							return ENXIO;
242						}
243
244						CmdBlkP->Packet.dest_unit = MapP->ID;
245						CmdBlkP->Packet.dest_port = BOOT_RUP;
246						CmdBlkP->Packet.src_unit  = 0;
247						CmdBlkP->Packet.src_port  = BOOT_RUP;
248						CmdBlkP->Packet.len	   = 0x84;
249						CmdBlkP->Packet.data[0]   = IDENTIFY;
250						CmdBlkP->Packet.data[1]   = 0;
251						CmdBlkP->Packet.data[2]   = IdRta.ID;
252
253						if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
254							rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: Failed to queue command\n");
255							return EIO;
256						}
257						return 0;
258					}
259				}
260			}
261		}
262	}
263	return ENOENT;
264}
265
266
267int
268RIOKillNeighbour(p, arg)
269struct rio_info *	p;
270caddr_t arg;
271{
272	uint Host;
273	uint ID;
274	struct Host *HostP;
275	struct CmdBlk *CmdBlkP;
276
277	rio_dprintk (RIO_DEBUG_CMD, "KILL HOST NEIGHBOUR\n");
278
279	if ( copyin( (int)arg, (caddr_t)&KillUnit, sizeof(KillUnit) ) == COPYFAIL ) {
280		rio_dprintk (RIO_DEBUG_CMD, "RIO_KILL_NEIGHBOUR copy failed\n");
281		p->RIOError.Error = COPYIN_FAILED;
282		return EFAULT;
283	}
284
285	if ( KillUnit.Link > 3 )
286		return ENXIO;
287
288	CmdBlkP = RIOGetCmdBlk();
289
290	if ( !CmdBlkP ) {
291		rio_dprintk (RIO_DEBUG_CMD, "UFOAD: GetCmdBlk failed\n");
292		return ENXIO;
293	}
294
295	CmdBlkP->Packet.dest_unit = 0;
296	CmdBlkP->Packet.src_unit  = 0;
297	CmdBlkP->Packet.dest_port = BOOT_RUP;
298	CmdBlkP->Packet.src_port  = BOOT_RUP;
299	CmdBlkP->Packet.len	   = 0x84;
300	CmdBlkP->Packet.data[0]   = UFOAD;
301	CmdBlkP->Packet.data[1]   = KillUnit.Link;
302	CmdBlkP->Packet.data[2]   = UFOAD_MAGIC & 0xFF;
303	CmdBlkP->Packet.data[3]   = (UFOAD_MAGIC >> 8) & 0xFF;
304
305	for ( Host = 0; Host < p->RIONumHosts; Host++ ) {
306		ID = 0;
307		HostP = &p->RIOHosts[Host];
308
309		if ( HostP->UniqueNum == KillUnit.UniqueNum ) {
310			if ( RIOQueueCmdBlk( HostP, RTAS_PER_HOST+KillUnit.Link,
311							CmdBlkP) == RIO_FAIL ) {
312				rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
313				return EIO;
314			}
315			return 0;
316		}
317
318		for ( ID=0; ID < RTAS_PER_HOST; ID++ ) {
319			if ( HostP->Mapping[ID].RtaUniqueNum == KillUnit.UniqueNum ) {
320				CmdBlkP->Packet.dest_unit = ID+1;
321				if ( RIOQueueCmdBlk( HostP, ID, CmdBlkP) == RIO_FAIL ) {
322					rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
323					return EIO;
324				}
325				return 0;
326			}
327		}
328	}
329	RIOFreeCmdBlk( CmdBlkP );
330	return ENXIO;
331}
332
333int
334RIOSuspendBootRta(HostP, ID, Link)
335struct Host *HostP;
336int ID;
337int Link;
338{
339	struct CmdBlk *CmdBlkP;
340
341	rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link);
342
343	CmdBlkP = RIOGetCmdBlk();
344
345	if ( !CmdBlkP ) {
346		rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: GetCmdBlk failed\n");
347		return ENXIO;
348	}
349
350	CmdBlkP->Packet.dest_unit = ID;
351	CmdBlkP->Packet.dest_port = BOOT_RUP;
352	CmdBlkP->Packet.src_unit  = 0;
353	CmdBlkP->Packet.src_port  = BOOT_RUP;
354	CmdBlkP->Packet.len	   = 0x84;
355	CmdBlkP->Packet.data[0]   = IWAIT;
356	CmdBlkP->Packet.data[1]   = Link;
357	CmdBlkP->Packet.data[2]   = IWAIT_MAGIC & 0xFF;
358	CmdBlkP->Packet.data[3]   = (IWAIT_MAGIC >> 8) & 0xFF;
359
360	if ( RIOQueueCmdBlk( HostP, ID - 1, CmdBlkP) == RIO_FAIL ) {
361		rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: Failed to queue iwait command\n");
362		return EIO;
363	}
364	return 0;
365}
366
367int
368RIOFoadWakeup(p)
369struct rio_info *	p;
370{
371	int port;
372	register struct Port *PortP;
373	unsigned long flags;
374
375	for ( port=0; port<RIO_PORTS; port++) {
376		PortP = p->RIOPortp[port];
377
378		rio_spin_lock_irqsave(&PortP->portSem, flags);
379		PortP->Config = 0;
380		PortP->State = 0;
381		PortP->InUse = NOT_INUSE;
382		PortP->PortState = 0;
383		PortP->FlushCmdBodge = 0;
384		PortP->ModemLines = 0;
385		PortP->ModemState = 0;
386		PortP->CookMode = 0;
387		PortP->ParamSem = 0;
388		PortP->Mapped = 0;
389		PortP->WflushFlag = 0;
390		PortP->MagicFlags = 0;
391		PortP->RxDataStart = 0;
392		PortP->TxBufferIn = 0;
393		PortP->TxBufferOut = 0;
394		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
395	}
396	return(0);
397}
398
399/*
400** Incoming command on the COMMAND_RUP to be processed.
401*/
402int
403RIOCommandRup(p, Rup, HostP, PacketP)
404struct rio_info *	p;
405uint Rup;
406struct Host *HostP;
407PKT *PacketP;
408{
409	struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data;
410	struct Port *PortP;
411	struct UnixRup *UnixRupP;
412	ushort SysPort;
413	ushort ReportedModemStatus;
414	ushort rup;
415	ushort subCommand;
416	unsigned long flags;
417
418	func_enter ();
419
420#ifdef CHECK
421	CheckHost( Host );
422	CheckHostP( HostP );
423	CheckPacketP( PacketP );
424#endif
425
426	/*
427	** 16 port RTA note:
428	** Command rup packets coming from the RTA will have pkt->data[1] (which
429	** translates to PktCmdP->PhbNum) set to the host port number for the
430	** particular unit. To access the correct BaseSysPort for a 16 port RTA,
431	** we can use PhbNum to get the rup number for the appropriate 8 port
432	** block (for the first block, this should be equal to 'Rup').
433	*/
434	rup = RBYTE(PktCmdP->PhbNum) / (ushort)PORTS_PER_RTA;
435	UnixRupP = &HostP->UnixRups[rup];
436	SysPort = UnixRupP->BaseSysPort +
437			(RBYTE(PktCmdP->PhbNum) % (ushort)PORTS_PER_RTA);
438	rio_dprintk (RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort);
439
440#ifdef CHECK
441	CheckRup( rup );
442	CheckUnixRupP( UnixRupP );
443#endif
444	if ( UnixRupP->BaseSysPort == NO_PORT ) {
445		rio_dprintk (RIO_DEBUG_CMD, "OBSCURE ERROR!\n");
446		rio_dprintk (RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n");
447		rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Host number %d, name ``%s''\n",
448			     HostP-p->RIOHosts, HostP->Name );
449		rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Rup number  0x%x\n", rup);
450
451		if ( Rup >= (ushort)MAX_RUP ) {
452			rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n",
453				     HostP->Mapping[Rup].Name);
454		} else
455			rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n",
456				     ('A' + Rup - MAX_RUP), HostP->Name);
457
458		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n",
459			     PacketP->dest_unit, PacketP->dest_port );
460		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Source	  0x%x:0x%x\n",
461			     PacketP->src_unit, PacketP->src_port );
462		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Length	  0x%x (%d)\n", PacketP->len,PacketP->len );
463		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Control	 0x%x (%d)\n", PacketP->control, PacketP->control);
464		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Check	   0x%x (%d)\n", PacketP->csum, PacketP->csum );
465		rio_dprintk (RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, "
466					"Command Code 0x%x\n", PktCmdP->PhbNum, PktCmdP->Command );
467		return TRUE;
468	}
469
470#ifdef CHECK
471	CheckSysPort( SysPort );
472#endif
473	PortP = p->RIOPortp[ SysPort ];
474	rio_spin_lock_irqsave(&PortP->portSem, flags);
475	switch( RBYTE(PktCmdP->Command) ) {
476		case BREAK_RECEIVED:
477			rio_dprintk (RIO_DEBUG_CMD, "Received a break!\n");
478			/* If the current line disc. is not multi-threading and
479	   			the current processor is not the default, reset rup_intr
480	   			and return FALSE to ensure that the command packet is
481	   			not freed. */
482			/* Call tmgr HANGUP HERE */
483			/* Fix this later when every thing works !!!! RAMRAJ */
484			gs_got_break (&PortP->gs);
485			break;
486
487		case COMPLETE:
488			rio_dprintk (RIO_DEBUG_CMD, "Command complete on phb %d host %d\n",
489			     RBYTE(PktCmdP->PhbNum), HostP-p->RIOHosts);
490			subCommand = 1;
491			switch (RBYTE(PktCmdP->SubCommand)) {
492				case MEMDUMP :
493			rio_dprintk (RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n",
494				     RBYTE(PktCmdP->SubCommand), RWORD(PktCmdP->SubAddr));
495					break;
496				case READ_REGISTER :
497			rio_dprintk (RIO_DEBUG_CMD, "Read register (0x%x)\n", RWORD(PktCmdP->SubAddr));
498					p->CdRegister = (RBYTE(PktCmdP->ModemStatus) & MSVR1_HOST);
499					break;
500				default :
501					subCommand = 0;
502				break;
503			}
504			if (subCommand)
505				break;
506			rio_dprintk (RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n",
507				     RBYTE(PktCmdP->PortStatus),PortP->PortState);
508			if (PortP->PortState != RBYTE(PktCmdP->PortStatus)) {
509				rio_dprintk (RIO_DEBUG_CMD, "Mark status & wakeup\n");
510				PortP->PortState = RBYTE(PktCmdP->PortStatus);
511				/* What should we do here ...
512				wakeup( &PortP->PortState );
513				*/
514		} else
515			rio_dprintk (RIO_DEBUG_CMD, "No change\n");
516
517			/* FALLTHROUGH */
518		case MODEM_STATUS:
519			/*
520			** Knock out the tbusy and tstop bits, as these are not relevant
521			** to the check for modem status change (they're just there because
522			** it's a convenient place to put them!).
523			*/
524			ReportedModemStatus = RBYTE(PktCmdP->ModemStatus);
525			if ((PortP->ModemState & MSVR1_HOST) ==
526					(ReportedModemStatus & MSVR1_HOST)) {
527				rio_dprintk (RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState);
528				/*
529				** Update ModemState just in case tbusy or tstop states have
530				** changed.
531				*/
532				PortP->ModemState = ReportedModemStatus;
533			}
534			else {
535				rio_dprintk (RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n",
536				     PortP->ModemState, ReportedModemStatus);
537				PortP->ModemState = ReportedModemStatus;
538#ifdef MODEM_SUPPORT
539				if ( PortP->Mapped ) {
540				/***********************************************************\
541				*************************************************************
542				***													   ***
543				***		  M O D E M   S T A T E   C H A N G E		  ***
544				***													   ***
545				*************************************************************
546				\***********************************************************/
547				/*
548				** If the device is a modem, then check the modem
549				** carrier.
550				*/
551				if (PortP->gs.tty == NULL)
552					break;
553				if (PortP->gs.tty->termios == NULL)
554					break;
555
556				if (!(PortP->gs.tty->termios->c_cflag & CLOCAL) &&
557				((PortP->State & (RIO_MOPEN|RIO_WOPEN)))) {
558
559					rio_dprintk (RIO_DEBUG_CMD, "Is there a Carrier?\n");
560			/*
561			** Is there a carrier?
562			*/
563					if ( PortP->ModemState & MSVR1_CD ) {
564			/*
565			** Has carrier just appeared?
566			*/
567						if (!(PortP->State & RIO_CARR_ON)) {
568							rio_dprintk (RIO_DEBUG_CMD, "Carrier just came up.\n");
569							PortP->State |= RIO_CARR_ON;
570				/*
571				** wakeup anyone in WOPEN
572				*/
573							if (PortP->State & (PORT_ISOPEN | RIO_WOPEN) )
574								wake_up_interruptible (&PortP->gs.open_wait);
575#ifdef STATS
576				PortP->Stat.ModemOnCnt++;
577#endif
578			}
579					} else {
580			/*
581			** Has carrier just dropped?
582			*/
583						if (PortP->State & RIO_CARR_ON) {
584							if (PortP->State & (PORT_ISOPEN|RIO_WOPEN|RIO_MOPEN))
585								tty_hangup (PortP->gs.tty);
586							PortP->State &= ~RIO_CARR_ON;
587							rio_dprintk (RIO_DEBUG_CMD, "Carrirer just went down\n");
588#ifdef STATS
589				PortP->Stat.ModemOffCnt++;
590#endif
591			}
592			}
593		}
594		}
595#endif
596			}
597			break;
598
599		default:
600			rio_dprintk (RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %d\n",
601			     RBYTE(PktCmdP->Command),HostP-p->RIOHosts);
602			break;
603	}
604	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
605
606	func_exit ();
607
608	return TRUE;
609}
610/*
611** The command mechanism:
612**	Each rup has a chain of commands associated with it.
613**	This chain is maintained by routines in this file.
614**	Periodically we are called and we run a quick check of all the
615**	active chains to determine if there is a command to be executed,
616**	and if the rup is ready to accept it.
617**
618*/
619
620/*
621** Allocate an empty command block.
622*/
623struct CmdBlk *
624RIOGetCmdBlk()
625{
626	struct CmdBlk *CmdBlkP;
627
628	CmdBlkP = (struct CmdBlk *)sysbrk(sizeof(struct CmdBlk));
629	if (CmdBlkP)
630		bzero(CmdBlkP, sizeof(struct CmdBlk));
631
632	return CmdBlkP;
633}
634
635/*
636** Return a block to the head of the free list.
637*/
638void
639RIOFreeCmdBlk(CmdBlkP)
640struct CmdBlk *CmdBlkP;
641{
642	sysfree((void *)CmdBlkP, sizeof(struct CmdBlk));
643}
644
645/*
646** attach a command block to the list of commands to be performed for
647** a given rup.
648*/
649int
650RIOQueueCmdBlk(HostP, Rup, CmdBlkP)
651struct Host *HostP;
652uint Rup;
653struct CmdBlk *CmdBlkP;
654{
655	struct CmdBlk **Base;
656	struct UnixRup *UnixRupP;
657	unsigned long flags;
658
659#ifdef CHECK
660	CheckHostP( HostP );
661	CheckRup( Rup );
662	CheckCmdBlkP( CmdBlkP );
663#endif
664	if ( Rup >= (ushort)(MAX_RUP+LINKS_PER_UNIT) ) {
665		rio_dprintk (RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlk\n",Rup);
666		RIOFreeCmdBlk( CmdBlkP );
667		return RIO_FAIL;
668	}
669
670	UnixRupP = &HostP->UnixRups[Rup];
671
672	rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
673
674	/*
675	** If the RUP is currently inactive, then put the request
676	** straight on the RUP....
677	*/
678	if ( (UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) &&
679	     (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE ) &&
680		(CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP)(CmdBlkP->PreArg,CmdBlkP)
681							:TRUE)) {
682		rio_dprintk (RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n",
683					     CmdBlkP->Packet.data[0]);
684
685
686		/*
687		** Whammy! blat that pack!
688		*/
689		HostP->Copy( (caddr_t)&CmdBlkP->Packet,
690			RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt ), sizeof(PKT) );
691
692		/*
693		** place command packet on the pending position.
694		*/
695		UnixRupP->CmdPendingP = CmdBlkP;
696
697		/*
698		** set the command register
699		*/
700		WWORD(UnixRupP->RupP->txcontrol , TX_PACKET_READY);
701
702		rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
703
704		return RIO_SUCCESS;
705	}
706	rio_dprintk (RIO_DEBUG_CMD, "RUP active - en-queing\n");
707
708	if ( UnixRupP->CmdsWaitingP != NULL)
709		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command waiting\n");
710	if ( UnixRupP->CmdPendingP != NULL )
711		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command pending\n");
712	if ( RWORD(UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE )
713		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command rup not ready\n");
714
715	Base = &UnixRupP->CmdsWaitingP;
716
717	rio_dprintk (RIO_DEBUG_CMD, "First try to queue cmdblk 0x%x at 0x%x\n", (int)CmdBlkP,(int)Base);
718
719	while ( *Base ) {
720		rio_dprintk (RIO_DEBUG_CMD, "Command cmdblk 0x%x here\n", (int)(*Base));
721		Base = &((*Base)->NextP);
722		rio_dprintk (RIO_DEBUG_CMD, "Now try to queue cmd cmdblk 0x%x at 0x%x\n",
723					     (int)CmdBlkP,(int)Base);
724	}
725
726	rio_dprintk (RIO_DEBUG_CMD, "Will queue cmdblk 0x%x at 0x%x\n",(int)CmdBlkP,(int)Base);
727
728	*Base = CmdBlkP;
729
730	CmdBlkP->NextP = NULL;
731
732	rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
733
734	return RIO_SUCCESS;
735}
736
737/*
738** Here we go - if there is an empty rup, fill it!
739** must be called at splrio() or higher.
740*/
741void
742RIOPollHostCommands(p, HostP)
743struct rio_info *	p;
744struct Host *		HostP;
745{
746	register struct CmdBlk *CmdBlkP;
747	register struct UnixRup *UnixRupP;
748	struct PKT *PacketP;
749	ushort Rup;
750	unsigned long flags;
751
752
753	Rup = MAX_RUP+LINKS_PER_UNIT;
754
755	do {	/* do this loop for each RUP */
756		/*
757		** locate the rup we are processing & lock it
758		*/
759		UnixRupP = &HostP->UnixRups[--Rup];
760
761		spin_lock_irqsave(&UnixRupP->RupLock, flags);
762
763		/*
764		** First check for incoming commands:
765		*/
766		if ( RWORD(UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE ) {
767			int FreeMe;
768
769			PacketP =(PKT *)RIO_PTR(HostP->Caddr,RWORD(UnixRupP->RupP->rxpkt));
770
771			ShowPacket( DBG_CMD, PacketP );
772
773			switch ( RBYTE(PacketP->dest_port) ) {
774				case BOOT_RUP:
775					rio_dprintk (RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'\n",
776						RBYTE(PacketP->len) & 0x80 ? "Command":"Data",
777							     RBYTE(PacketP->data[0]));
778					rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
779					FreeMe= RIOBootRup(p, Rup,HostP,PacketP);
780					rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
781					break;
782
783				case COMMAND_RUP:
784					/*
785					** Free the RUP lock as loss of carrier causes a
786					** ttyflush which will (eventually) call another
787					** routine that uses the RUP lock.
788					*/
789					rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
790					FreeMe= RIOCommandRup(p, Rup,HostP,PacketP);
791					if (PacketP->data[5] == MEMDUMP) {
792						rio_dprintk (RIO_DEBUG_CMD, "Memdump from 0x%x complete\n",
793								     *(ushort *) &(PacketP->data[6]));
794						HostP->Copy( (caddr_t)&(PacketP->data[8]),
795								(caddr_t)p->RIOMemDump, 32 );
796					}
797					rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
798					break;
799
800				case ROUTE_RUP:
801					rio_spin_unlock_irqrestore( &UnixRupP->RupLock, flags);
802					FreeMe = RIORouteRup(p, Rup, HostP, PacketP );
803					rio_spin_lock_irqsave( &UnixRupP->RupLock, flags );
804					break;
805
806				default:
807					rio_dprintk (RIO_DEBUG_CMD, "Unknown RUP %d\n", RBYTE(PacketP->dest_port));
808					FreeMe = 1;
809					break;
810			}
811
812			if ( FreeMe ) {
813				rio_dprintk (RIO_DEBUG_CMD, "Free processed incoming command packet\n");
814				put_free_end(HostP,PacketP);
815
816				WWORD(UnixRupP->RupP->rxcontrol , RX_RUP_INACTIVE);
817
818				if ( RWORD(UnixRupP->RupP->handshake)==PHB_HANDSHAKE_SET ) {
819					rio_dprintk (RIO_DEBUG_CMD, "Handshake rup %d\n",Rup);
820					WWORD(UnixRupP->RupP->handshake,
821						PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
822				}
823			}
824		}
825
826		/*
827		** IF a command was running on the port,
828		** and it has completed, then tidy it up.
829		*/
830		if ( (CmdBlkP = UnixRupP->CmdPendingP) && /* ASSIGN! */
831		     (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
832			/*
833			** we are idle.
834			** there is a command in pending.
835			** Therefore, this command has finished.
836			** So, wakeup whoever is waiting for it (and tell them
837			** what happened).
838			*/
839			if ( CmdBlkP->Packet.dest_port == BOOT_RUP )
840				rio_dprintk (RIO_DEBUG_CMD, "Free Boot %s Command Block '%x'\n",
841						CmdBlkP->Packet.len & 0x80 ? "Command":"Data",
842							     CmdBlkP->Packet.data[0]);
843
844			rio_dprintk (RIO_DEBUG_CMD, "Command 0x%x completed\n",(int)CmdBlkP);
845
846			/*
847			** Clear the Rup lock to prevent mutual exclusion.
848			*/
849			if ( CmdBlkP->PostFuncP ) {
850				rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
851				(*CmdBlkP->PostFuncP) (CmdBlkP->PostArg,CmdBlkP);
852				rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
853			}
854
855			/*
856			** ....clear the pending flag....
857			*/
858			UnixRupP->CmdPendingP = NULL;
859
860			/*
861			** ....and return the command block to the freelist.
862			*/
863			RIOFreeCmdBlk( CmdBlkP );
864		}
865
866		/*
867		** If there is a command for this rup, and the rup
868		** is idle, then process the command
869		*/
870		if ( (CmdBlkP = UnixRupP->CmdsWaitingP) && /* ASSIGN! */
871			(UnixRupP->CmdPendingP == NULL) &&
872		     (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
873			/*
874			** if the pre-function is non-zero, call it.
875			** If it returns RIO_FAIL then don't
876			** send this command yet!
877			*/
878#ifdef CHECK
879			CheckCmdBlkP (CmdBlkP);
880#endif
881			if ( !(CmdBlkP->PreFuncP ?
882				(*CmdBlkP->PreFuncP)(CmdBlkP->PreArg, CmdBlkP) : TRUE)) {
883				rio_dprintk (RIO_DEBUG_CMD, "Not ready to start command 0x%x\n",(int)CmdBlkP);
884			}
885			else {
886				rio_dprintk (RIO_DEBUG_CMD, "Start new command 0x%x Cmd byte is 0x%x\n",
887							     (int)CmdBlkP, CmdBlkP->Packet.data[0]);
888				/*
889				** Whammy! blat that pack!
890				*/
891#ifdef CHECK
892				CheckPacketP ((PKT *)RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt));
893#endif
894				HostP->Copy( (caddr_t)&CmdBlkP->Packet,
895					RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt), sizeof(PKT));
896
897				/*
898				** remove the command from the rup command queue...
899				*/
900				UnixRupP->CmdsWaitingP = CmdBlkP->NextP;
901
902				/*
903				** ...and place it on the pending position.
904				*/
905				UnixRupP->CmdPendingP = CmdBlkP;
906
907				/*
908				** set the command register
909				*/
910				WWORD(UnixRupP->RupP->txcontrol,TX_PACKET_READY);
911
912				/*
913				** the command block will be freed
914				** when the command has been processed.
915				*/
916			}
917		}
918		spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
919	} while ( Rup );
920}
921
922
923/*
924** Return the length of the named string
925*/
926int
927RIOStrlen(Str)
928register char *Str;
929{
930	register int len = 0;
931
932	while ( *Str++ )
933		len++;
934	return len;
935}
936
937/*
938** compares s1 to s2 and return 0 if they match.
939*/
940int
941RIOStrCmp(s1, s2)
942register char *s1;
943register char *s2;
944{
945	while ( *s1 && *s2 && *s1==*s2 )
946		s1++, s2++;
947	return *s1-*s2;
948}
949
950/*
951** compares s1 to s2 for upto n bytes and return 0 if they match.
952*/
953int
954RIOStrnCmp(s1, s2, n)
955register char *s1;
956register char *s2;
957int n;
958{
959	while ( n && *s1 && *s2 && *s1==*s2 )
960		n--, s1++, s2++;
961	return n ? *s1!=*s2 : 0;
962}
963
964/*
965** copy up to 'len' bytes from 'from' to 'to'.
966*/
967void
968RIOStrNCpy(to, from, len)
969char *to;
970char *from;
971int len;
972{
973	while ( len-- && (*to++ = *from++) )
974		;
975	to[-1]='\0';
976}
977
978int
979RIOWFlushMark(iPortP, CmdBlkP)
980int iPortP;
981struct CmdBlk *CmdBlkP;
982{
983	struct Port *	PortP = (struct Port *)iPortP;
984	unsigned long flags;
985
986	rio_spin_lock_irqsave(&PortP->portSem, flags);
987#ifdef CHECK
988	CheckPortP( PortP );
989#endif
990	PortP->WflushFlag++;
991	PortP->MagicFlags |= MAGIC_FLUSH;
992	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
993	return RIOUnUse( iPortP, CmdBlkP );
994}
995
996int
997RIORFlushEnable(iPortP, CmdBlkP)
998int iPortP;
999struct CmdBlk *CmdBlkP;
1000{
1001	struct Port *	PortP = (struct Port *)iPortP;
1002	PKT *PacketP;
1003	unsigned long flags;
1004
1005	rio_spin_lock_irqsave(&PortP->portSem, flags);
1006
1007	while ( can_remove_receive(&PacketP, PortP) ) {
1008		remove_receive(PortP);
1009		ShowPacket(DBG_PROC, PacketP );
1010		put_free_end( PortP->HostP, PacketP );
1011	}
1012
1013	if ( RWORD(PortP->PhbP->handshake)==PHB_HANDSHAKE_SET ) {
1014		/*
1015		** MAGIC! (Basically, handshake the RX buffer, so that
1016		** the RTAs upstream can be re-enabled.)
1017		*/
1018		rio_dprintk (RIO_DEBUG_CMD, "Util: Set RX handshake bit\n");
1019		WWORD(PortP->PhbP->handshake, PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
1020	}
1021	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1022	return RIOUnUse( iPortP, CmdBlkP );
1023}
1024
1025int
1026RIOUnUse(iPortP, CmdBlkP)
1027int iPortP;
1028struct CmdBlk *CmdBlkP;
1029{
1030	struct Port *	PortP = (struct Port *)iPortP;
1031	unsigned long flags;
1032
1033	rio_spin_lock_irqsave(&PortP->portSem, flags);
1034
1035#ifdef CHECK
1036	CheckPortP( PortP );
1037#endif
1038	rio_dprintk (RIO_DEBUG_CMD, "Decrement in use count for port\n");
1039
1040	if (PortP->InUse) {
1041		if ( --PortP->InUse != NOT_INUSE ) {
1042			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1043			return 0;
1044		}
1045	}
1046	/*
1047	** While PortP->InUse is set (i.e. a preemptive command has been sent to
1048	** the RTA and is awaiting completion), any transmit data is prevented from
1049	** being transferred from the write queue into the transmit packets
1050	** (add_transmit) and no furthur transmit interrupt will be sent for that
1051	** data. The next interrupt will occur up to 500ms later (RIOIntr is called
1052	** twice a second as a saftey measure). This was the case when kermit was
1053	** used to send data into a RIO port. After each packet was sent, TCFLSH
1054	** was called to flush the read queue preemptively. PortP->InUse was
1055	** incremented, thereby blocking the 6 byte acknowledgement packet
1056	** transmitted back. This acknowledgment hung around for 500ms before
1057	** being sent, thus reducing input performance substantially!.
1058	** When PortP->InUse becomes NOT_INUSE, we must ensure that any data
1059	** hanging around in the transmit buffer is sent immediately.
1060	*/
1061	WWORD(PortP->HostP->ParmMapP->tx_intr, 1);
1062	/* What to do here ..
1063	wakeup( (caddr_t)&(PortP->InUse) );
1064	*/
1065	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
1066	return 0;
1067}
1068
1069void
1070ShowPacket(Flags, PacketP)
1071uint Flags;
1072struct PKT *PacketP;
1073{
1074}
1075
1076/*
1077**
1078** How to use this file:
1079**
1080** To send a command down a rup, you need to allocate a command block, fill
1081** in the packet information, fill in the command number, fill in the pre-
1082** and post- functions and arguments, and then add the command block to the
1083** queue of command blocks for the port in question. When the port is idle,
1084** then the pre-function will be called. If this returns RIO_FAIL then the
1085** command will be re-queued and tried again at a later date (probably in one
1086** clock tick). If the pre-function returns NOT RIO_FAIL, then the command
1087** packet will be queued on the RUP, and the txcontrol field set to the
1088** command number. When the txcontrol field has changed from being the
1089** command number, then the post-function will be called, with the argument
1090** specified earlier, a pointer to the command block, and the value of
1091** txcontrol.
1092**
1093** To allocate a command block, call RIOGetCmdBlk(). This returns a pointer
1094** to the command block structure allocated, or NULL if there aren't any.
1095** The block will have been zeroed for you.
1096**
1097** The structure has the following fields:
1098**
1099** struct CmdBlk
1100** {
1101**	 struct CmdBlk *NextP;		  ** Pointer to next command block   **
1102**	 struct PKT	 Packet;		** A packet, to copy to the rup	**
1103**			int	 (*PreFuncP)();  ** The func to call to check if OK **
1104**			int	 PreArg;		** The arg for the func			**
1105**			int	 (*PostFuncP)(); ** The func to call when completed **
1106**			int	 PostArg;	   ** The arg for the func			**
1107** };
1108**
1109** You need to fill in ALL fields EXCEPT NextP, which is used to link the
1110** blocks together either on the free list or on the Rup list.
1111**
1112** Packet is an actual packet structure to be filled in with the packet
1113** information associated with the command. You need to fill in everything,
1114** as the command processore doesn't process the command packet in any way.
1115**
1116** The PreFuncP is called before the packet is enqueued on the host rup.
1117** PreFuncP is called as (*PreFuncP)(PreArg, CmdBlkP);. PreFuncP must
1118** return !RIO_FAIL to have the packet queued on the rup, and RIO_FAIL
1119** if the packet is NOT to be queued.
1120**
1121** The PostFuncP is called when the command has completed. It is called
1122** as (*PostFuncP)(PostArg, CmdBlkP, txcontrol);. PostFuncP is not expected
1123** to return a value. PostFuncP does NOT need to free the command block,
1124** as this happens automatically after PostFuncP returns.
1125**
1126** Once the command block has been filled in, it is attached to the correct
1127** queue by calling RIOQueueCmdBlk( HostP, Rup, CmdBlkP ) where HostP is
1128** a pointer to the struct Host, Rup is the NUMBER of the rup (NOT a pointer
1129** to it!), and CmdBlkP is the pointer to the command block allocated using
1130** RIOGetCmdBlk().
1131**
1132*/
1133