aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/rio/rioroute.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/rio/rioroute.c')
-rw-r--r--drivers/char/rio/rioroute.c1572
1 files changed, 713 insertions, 859 deletions
diff --git a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c
index e9564c9fb37c..0f4cd33ba641 100644
--- a/drivers/char/rio/rioroute.c
+++ b/drivers/char/rio/rioroute.c
@@ -93,625 +93,517 @@ static void RIOConCon(struct rio_info *, struct Host *, uint, uint, uint, uint,
93** Incoming on the ROUTE_RUP 93** Incoming on the ROUTE_RUP
94** I wrote this while I was tired. Forgive me. 94** I wrote this while I was tired. Forgive me.
95*/ 95*/
96int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP ) 96int RIORouteRup(struct rio_info *p, uint Rup, struct Host *HostP, PKT * PacketP)
97{ 97{
98 struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data; 98 struct PktCmd *PktCmdP = (struct PktCmd *) PacketP->data;
99 struct PktCmd_M *PktReplyP; 99 struct PktCmd_M *PktReplyP;
100 struct CmdBlk *CmdBlkP; 100 struct CmdBlk *CmdBlkP;
101 struct Port *PortP; 101 struct Port *PortP;
102 struct Map *MapP; 102 struct Map *MapP;
103 struct Top *TopP; 103 struct Top *TopP;
104 int ThisLink, ThisLinkMin, ThisLinkMax; 104 int ThisLink, ThisLinkMin, ThisLinkMax;
105 int port; 105 int port;
106 int Mod, Mod1, Mod2; 106 int Mod, Mod1, Mod2;
107 ushort RtaType; 107 ushort RtaType;
108 uint RtaUniq; 108 uint RtaUniq;
109 uint ThisUnit, ThisUnit2; /* 2 ids to accommodate 16 port RTA */ 109 uint ThisUnit, ThisUnit2; /* 2 ids to accommodate 16 port RTA */
110 uint OldUnit, NewUnit, OldLink, NewLink; 110 uint OldUnit, NewUnit, OldLink, NewLink;
111 char *MyType, *MyName; 111 char *MyType, *MyName;
112 int Lies; 112 int Lies;
113 unsigned long flags; 113 unsigned long flags;
114 114
115#ifdef STACK 115#ifdef STACK
116 RIOStackCheck("RIORouteRup"); 116 RIOStackCheck("RIORouteRup");
117#endif 117#endif
118#ifdef CHECK 118#ifdef CHECK
119 CheckPacketP(PacketP); 119 CheckPacketP(PacketP);
120 CheckHostP(HostP); 120 CheckHostP(HostP);
121 CheckRup(Rup); 121 CheckRup(Rup);
122 CheckHost(Host); 122 CheckHost(Host);
123#endif 123#endif
124 /*
125 ** Is this unit telling us it's current link topology?
126 */
127 if ( RBYTE(PktCmdP->Command) == ROUTE_TOPOLOGY )
128 {
129 MapP = HostP->Mapping;
130
131 /*
132 ** The packet can be sent either by the host or by an RTA.
133 ** If it comes from the host, then we need to fill in the
134 ** Topology array in the host structure. If it came in
135 ** from an RTA then we need to fill in the Mapping structure's
136 ** Topology array for the unit.
137 */
138 if ( Rup >= (ushort)MAX_RUP )
139 {
140 ThisUnit = HOST_ID;
141 TopP = HostP->Topology;
142 MyType = "Host";
143 MyName = HostP->Name;
144 ThisLinkMin = ThisLinkMax = Rup - MAX_RUP;
145 }
146 else
147 {
148 ThisUnit = Rup+1;
149 TopP = HostP->Mapping[Rup].Topology;
150 MyType = "RTA";
151 MyName = HostP->Mapping[Rup].Name;
152 ThisLinkMin = 0;
153 ThisLinkMax = LINKS_PER_UNIT - 1;
154 }
155
156 /*
157 ** Lies will not be tolerated.
158 ** If any pair of links claim to be connected to the same
159 ** place, then ignore this packet completely.
160 */
161 Lies = 0;
162 for ( ThisLink=ThisLinkMin + 1; ThisLink <= ThisLinkMax; ThisLink++)
163 {
164 /*
165 ** it won't lie about network interconnect, total disconnects
166 ** and no-IDs. (or at least, it doesn't *matter* if it does)
167 */
168 if ( RBYTE(PktCmdP->RouteTopology[ThisLink].Unit) > (ushort)MAX_RUP )
169 continue;
170
171 for ( NewLink=ThisLinkMin; NewLink < ThisLink; NewLink++ )
172 {
173 if ( (RBYTE(PktCmdP->RouteTopology[ThisLink].Unit) ==
174 RBYTE(PktCmdP->RouteTopology[NewLink].Unit)) &&
175 (RBYTE(PktCmdP->RouteTopology[ThisLink].Link) ==
176 RBYTE(PktCmdP->RouteTopology[NewLink].Link)) )
177 {
178 Lies++;
179 }
180 }
181 }
182
183 if ( Lies )
184 {
185 rio_dprintk (RIO_DEBUG_ROUTE, "LIES! DAMN LIES! %d LIES!\n",Lies);
186 rio_dprintk (RIO_DEBUG_ROUTE, "%d:%c %d:%c %d:%c %d:%c\n",
187 RBYTE(PktCmdP->RouteTopology[0].Unit),
188 'A'+RBYTE(PktCmdP->RouteTopology[0].Link),
189 RBYTE(PktCmdP->RouteTopology[1].Unit),
190 'A'+RBYTE(PktCmdP->RouteTopology[1].Link),
191 RBYTE(PktCmdP->RouteTopology[2].Unit),
192 'A'+RBYTE(PktCmdP->RouteTopology[2].Link),
193 RBYTE(PktCmdP->RouteTopology[3].Unit),
194 'A'+RBYTE(PktCmdP->RouteTopology[3].Link));
195 return TRUE;
196 }
197
198 /*
199 ** now, process each link.
200 */
201 for ( ThisLink=ThisLinkMin; ThisLink <= ThisLinkMax; ThisLink++)
202 {
203 /*
204 ** this is what it was connected to
205 */
206 OldUnit = TopP[ThisLink].Unit;
207 OldLink = TopP[ThisLink].Link;
208
209 /*
210 ** this is what it is now connected to
211 */
212 NewUnit = RBYTE(PktCmdP->RouteTopology[ThisLink].Unit);
213 NewLink = RBYTE(PktCmdP->RouteTopology[ThisLink].Link);
214
215 if ( OldUnit != NewUnit || OldLink != NewLink )
216 {
217 /* 124 /*
218 ** something has changed! 125 ** Is this unit telling us it's current link topology?
219 */ 126 */
220 127 if (RBYTE(PktCmdP->Command) == ROUTE_TOPOLOGY) {
221 if ( NewUnit > MAX_RUP && 128 MapP = HostP->Mapping;
222 NewUnit != ROUTE_DISCONNECT && 129
223 NewUnit != ROUTE_NO_ID && 130 /*
224 NewUnit != ROUTE_INTERCONNECT ) 131 ** The packet can be sent either by the host or by an RTA.
225 { 132 ** If it comes from the host, then we need to fill in the
226 rio_dprintk (RIO_DEBUG_ROUTE, "I have a link from %s %s to unit %d:%d - I don't like it.\n", 133 ** Topology array in the host structure. If it came in
227 MyType, 134 ** from an RTA then we need to fill in the Mapping structure's
228 MyName, 135 ** Topology array for the unit.
229 NewUnit, 136 */
230 NewLink); 137 if (Rup >= (ushort) MAX_RUP) {
231 } 138 ThisUnit = HOST_ID;
232 else 139 TopP = HostP->Topology;
233 { 140 MyType = "Host";
234 /* 141 MyName = HostP->Name;
235 ** put the new values in 142 ThisLinkMin = ThisLinkMax = Rup - MAX_RUP;
236 */ 143 } else {
237 TopP[ThisLink].Unit = NewUnit; 144 ThisUnit = Rup + 1;
238 TopP[ThisLink].Link = NewLink; 145 TopP = HostP->Mapping[Rup].Topology;
239 146 MyType = "RTA";
240 RIOSetChange(p); 147 MyName = HostP->Mapping[Rup].Name;
241 148 ThisLinkMin = 0;
242 if ( OldUnit <= MAX_RUP ) 149 ThisLinkMax = LINKS_PER_UNIT - 1;
243 { 150 }
244 /* 151
245 ** If something has become bust, then re-enable them messages 152 /*
246 */ 153 ** Lies will not be tolerated.
247 if (! p->RIONoMessage) 154 ** If any pair of links claim to be connected to the same
248 RIOConCon(p,HostP,ThisUnit,ThisLink,OldUnit,OldLink,DISCONNECT); 155 ** place, then ignore this packet completely.
249 } 156 */
250 157 Lies = 0;
251 if ( ( NewUnit <= MAX_RUP ) && !p->RIONoMessage ) 158 for (ThisLink = ThisLinkMin + 1; ThisLink <= ThisLinkMax; ThisLink++) {
252 RIOConCon(p,HostP,ThisUnit,ThisLink,NewUnit,NewLink,CONNECT); 159 /*
253 160 ** it won't lie about network interconnect, total disconnects
254 if ( NewUnit == ROUTE_NO_ID ) 161 ** and no-IDs. (or at least, it doesn't *matter* if it does)
255 rio_dprintk (RIO_DEBUG_ROUTE, "%s %s (%c) is connected to an unconfigured unit.\n", 162 */
256 MyType,MyName,'A'+ThisLink); 163 if (RBYTE(PktCmdP->RouteTopology[ThisLink].Unit) > (ushort) MAX_RUP)
257 164 continue;
258 if ( NewUnit == ROUTE_INTERCONNECT ) 165
259 { 166 for (NewLink = ThisLinkMin; NewLink < ThisLink; NewLink++) {
260 if (! p->RIONoMessage) 167 if ((RBYTE(PktCmdP->RouteTopology[ThisLink].Unit) == RBYTE(PktCmdP->RouteTopology[NewLink].Unit)) && (RBYTE(PktCmdP->RouteTopology[ThisLink].Link) == RBYTE(PktCmdP->RouteTopology[NewLink].Link))) {
261 cprintf("%s '%s' (%c) is connected to another network.\n", MyType,MyName,'A'+ThisLink); 168 Lies++;
262 } 169 }
263 170 }
264 /* 171 }
265 ** perform an update for 'the other end', so that these messages 172
266 ** only appears once. Only disconnect the other end if it is pointing 173 if (Lies) {
267 ** at us! 174 rio_dprintk(RIO_DEBUG_ROUTE, "LIES! DAMN LIES! %d LIES!\n", Lies);
268 */ 175 rio_dprintk(RIO_DEBUG_ROUTE, "%d:%c %d:%c %d:%c %d:%c\n",
269 if ( OldUnit == HOST_ID ) 176 RBYTE(PktCmdP->RouteTopology[0].Unit),
270 { 177 'A' + RBYTE(PktCmdP->RouteTopology[0].Link),
271 if ( HostP->Topology[OldLink].Unit == ThisUnit && 178 RBYTE(PktCmdP->RouteTopology[1].Unit),
272 HostP->Topology[OldLink].Link == ThisLink ) 179 'A' + RBYTE(PktCmdP->RouteTopology[1].Link), RBYTE(PktCmdP->RouteTopology[2].Unit), 'A' + RBYTE(PktCmdP->RouteTopology[2].Link), RBYTE(PktCmdP->RouteTopology[3].Unit), 'A' + RBYTE(PktCmdP->RouteTopology[3].Link));
273 { 180 return TRUE;
274 rio_dprintk (RIO_DEBUG_ROUTE, "SETTING HOST (%c) TO DISCONNECTED!\n", OldLink+'A'); 181 }
275 HostP->Topology[OldLink].Unit = ROUTE_DISCONNECT; 182
276 HostP->Topology[OldLink].Link = NO_LINK; 183 /*
277 } 184 ** now, process each link.
278 else 185 */
279 { 186 for (ThisLink = ThisLinkMin; ThisLink <= ThisLinkMax; ThisLink++) {
280 rio_dprintk (RIO_DEBUG_ROUTE, "HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n", 187 /*
281 OldLink+'A',HostP->Mapping[ThisUnit-1].Name,ThisLink+'A'); 188 ** this is what it was connected to
282 } 189 */
283 } 190 OldUnit = TopP[ThisLink].Unit;
284 else if ( OldUnit <= MAX_RUP ) 191 OldLink = TopP[ThisLink].Link;
285 { 192
286 if ( HostP->Mapping[OldUnit-1].Topology[OldLink].Unit == ThisUnit && 193 /*
287 HostP->Mapping[OldUnit-1].Topology[OldLink].Link == ThisLink ) 194 ** this is what it is now connected to
288 { 195 */
289 rio_dprintk (RIO_DEBUG_ROUTE, "SETTING RTA %s (%c) TO DISCONNECTED!\n", 196 NewUnit = RBYTE(PktCmdP->RouteTopology[ThisLink].Unit);
290 HostP->Mapping[OldUnit-1].Name,OldLink+'A'); 197 NewLink = RBYTE(PktCmdP->RouteTopology[ThisLink].Link);
291 HostP->Mapping[OldUnit-1].Topology[OldLink].Unit=ROUTE_DISCONNECT; 198
292 HostP->Mapping[OldUnit-1].Topology[OldLink].Link=NO_LINK; 199 if (OldUnit != NewUnit || OldLink != NewLink) {
293 } 200 /*
294 else 201 ** something has changed!
295 { 202 */
296 rio_dprintk (RIO_DEBUG_ROUTE, "RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n", 203
297 HostP->Mapping[OldUnit-1].Name,OldLink+'A', 204 if (NewUnit > MAX_RUP && NewUnit != ROUTE_DISCONNECT && NewUnit != ROUTE_NO_ID && NewUnit != ROUTE_INTERCONNECT) {
298 HostP->Mapping[ThisUnit-1].Name,ThisLink+'A'); 205 rio_dprintk(RIO_DEBUG_ROUTE, "I have a link from %s %s to unit %d:%d - I don't like it.\n", MyType, MyName, NewUnit, NewLink);
299 } 206 } else {
300 } 207 /*
301 if ( NewUnit == HOST_ID ) 208 ** put the new values in
302 { 209 */
303 rio_dprintk (RIO_DEBUG_ROUTE, "MARKING HOST (%c) CONNECTED TO %s (%c)\n", 210 TopP[ThisLink].Unit = NewUnit;
304 NewLink+'A',MyName,ThisLink+'A'); 211 TopP[ThisLink].Link = NewLink;
305 HostP->Topology[NewLink].Unit = ThisUnit; 212
306 HostP->Topology[NewLink].Link = ThisLink; 213 RIOSetChange(p);
307 } 214
308 else if ( NewUnit <= MAX_RUP ) 215 if (OldUnit <= MAX_RUP) {
309 { 216 /*
310 rio_dprintk (RIO_DEBUG_ROUTE, "MARKING RTA %s (%c) CONNECTED TO %s (%c)\n", 217 ** If something has become bust, then re-enable them messages
311 HostP->Mapping[NewUnit-1].Name,NewLink+'A',MyName,ThisLink+'A'); 218 */
312 HostP->Mapping[NewUnit-1].Topology[NewLink].Unit=ThisUnit; 219 if (!p->RIONoMessage)
313 HostP->Mapping[NewUnit-1].Topology[NewLink].Link=ThisLink; 220 RIOConCon(p, HostP, ThisUnit, ThisLink, OldUnit, OldLink, DISCONNECT);
314 } 221 }
222
223 if ((NewUnit <= MAX_RUP) && !p->RIONoMessage)
224 RIOConCon(p, HostP, ThisUnit, ThisLink, NewUnit, NewLink, CONNECT);
225
226 if (NewUnit == ROUTE_NO_ID)
227 rio_dprintk(RIO_DEBUG_ROUTE, "%s %s (%c) is connected to an unconfigured unit.\n", MyType, MyName, 'A' + ThisLink);
228
229 if (NewUnit == ROUTE_INTERCONNECT) {
230 if (!p->RIONoMessage)
231 cprintf("%s '%s' (%c) is connected to another network.\n", MyType, MyName, 'A' + ThisLink);
232 }
233
234 /*
235 ** perform an update for 'the other end', so that these messages
236 ** only appears once. Only disconnect the other end if it is pointing
237 ** at us!
238 */
239 if (OldUnit == HOST_ID) {
240 if (HostP->Topology[OldLink].Unit == ThisUnit && HostP->Topology[OldLink].Link == ThisLink) {
241 rio_dprintk(RIO_DEBUG_ROUTE, "SETTING HOST (%c) TO DISCONNECTED!\n", OldLink + 'A');
242 HostP->Topology[OldLink].Unit = ROUTE_DISCONNECT;
243 HostP->Topology[OldLink].Link = NO_LINK;
244 } else {
245 rio_dprintk(RIO_DEBUG_ROUTE, "HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n", OldLink + 'A', HostP->Mapping[ThisUnit - 1].Name, ThisLink + 'A');
246 }
247 } else if (OldUnit <= MAX_RUP) {
248 if (HostP->Mapping[OldUnit - 1].Topology[OldLink].Unit == ThisUnit && HostP->Mapping[OldUnit - 1].Topology[OldLink].Link == ThisLink) {
249 rio_dprintk(RIO_DEBUG_ROUTE, "SETTING RTA %s (%c) TO DISCONNECTED!\n", HostP->Mapping[OldUnit - 1].Name, OldLink + 'A');
250 HostP->Mapping[OldUnit - 1].Topology[OldLink].Unit = ROUTE_DISCONNECT;
251 HostP->Mapping[OldUnit - 1].Topology[OldLink].Link = NO_LINK;
252 } else {
253 rio_dprintk(RIO_DEBUG_ROUTE, "RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n", HostP->Mapping[OldUnit - 1].Name, OldLink + 'A', HostP->Mapping[ThisUnit - 1].Name, ThisLink + 'A');
254 }
255 }
256 if (NewUnit == HOST_ID) {
257 rio_dprintk(RIO_DEBUG_ROUTE, "MARKING HOST (%c) CONNECTED TO %s (%c)\n", NewLink + 'A', MyName, ThisLink + 'A');
258 HostP->Topology[NewLink].Unit = ThisUnit;
259 HostP->Topology[NewLink].Link = ThisLink;
260 } else if (NewUnit <= MAX_RUP) {
261 rio_dprintk(RIO_DEBUG_ROUTE, "MARKING RTA %s (%c) CONNECTED TO %s (%c)\n", HostP->Mapping[NewUnit - 1].Name, NewLink + 'A', MyName, ThisLink + 'A');
262 HostP->Mapping[NewUnit - 1].Topology[NewLink].Unit = ThisUnit;
263 HostP->Mapping[NewUnit - 1].Topology[NewLink].Link = ThisLink;
264 }
265 }
266 RIOSetChange(p);
267 RIOCheckIsolated(p, HostP, OldUnit);
268 }
269 }
270 return TRUE;
315 } 271 }
316 RIOSetChange(p); 272
317 RIOCheckIsolated(p, HostP, OldUnit ); 273 /*
318 } 274 ** The only other command we recognise is a route_request command
319 } 275 */
320 return TRUE; 276 if (RBYTE(PktCmdP->Command) != ROUTE_REQUEST) {
321 } 277 rio_dprintk(RIO_DEBUG_ROUTE, "Unknown command %d received on rup %d host %d ROUTE_RUP\n", RBYTE(PktCmdP->Command), Rup, (int) HostP);
322 278 return TRUE;
323 /*
324 ** The only other command we recognise is a route_request command
325 */
326 if ( RBYTE(PktCmdP->Command) != ROUTE_REQUEST )
327 {
328 rio_dprintk (RIO_DEBUG_ROUTE, "Unknown command %d received on rup %d host %d ROUTE_RUP\n",
329 RBYTE(PktCmdP->Command),Rup,(int)HostP);
330 return TRUE;
331 }
332
333 RtaUniq = (RBYTE(PktCmdP->UniqNum[0])) +
334 (RBYTE(PktCmdP->UniqNum[1]) << 8) +
335 (RBYTE(PktCmdP->UniqNum[2]) << 16) +
336 (RBYTE(PktCmdP->UniqNum[3]) << 24);
337
338 /*
339 ** Determine if 8 or 16 port RTA
340 */
341 RtaType = GetUnitType(RtaUniq);
342
343 rio_dprintk (RIO_DEBUG_ROUTE, "Received a request for an ID for serial number %x\n", RtaUniq);
344
345 Mod = RBYTE(PktCmdP->ModuleTypes);
346 Mod1 = LONYBLE(Mod);
347 if (RtaType == TYPE_RTA16)
348 {
349 /*
350 ** Only one ident is set for a 16 port RTA. To make compatible
351 ** with 8 port, set 2nd ident in Mod2 to the same as Mod1.
352 */
353 Mod2 = Mod1;
354 rio_dprintk (RIO_DEBUG_ROUTE, "Backplane type is %s (all ports)\n",
355 p->RIOModuleTypes[Mod1].Name);
356 }
357 else
358 {
359 Mod2 = HINYBLE(Mod);
360 rio_dprintk (RIO_DEBUG_ROUTE, "Module types are %s (ports 0-3) and %s (ports 4-7)\n",
361 p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name);
362 }
363
364 if ( RtaUniq == 0xffffffff )
365 {
366 ShowPacket( DBG_SPECIAL, PacketP );
367 }
368
369 /*
370 ** try to unhook a command block from the command free list.
371 */
372 if ( !(CmdBlkP = RIOGetCmdBlk()) )
373 {
374 rio_dprintk (RIO_DEBUG_ROUTE, "No command blocks to route RTA! come back later.\n");
375 return 0;
376 }
377
378 /*
379 ** Fill in the default info on the command block
380 */
381 CmdBlkP->Packet.dest_unit = Rup;
382 CmdBlkP->Packet.dest_port = ROUTE_RUP;
383 CmdBlkP->Packet.src_unit = HOST_ID;
384 CmdBlkP->Packet.src_port = ROUTE_RUP;
385 CmdBlkP->Packet.len = PKT_CMD_BIT | 1;
386 CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL;
387 PktReplyP = (struct PktCmd_M *)CmdBlkP->Packet.data;
388
389 if (! RIOBootOk(p, HostP, RtaUniq))
390 {
391 rio_dprintk (RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n",
392 RtaUniq);
393 PktReplyP->Command = ROUTE_FOAD;
394 HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7);
395 RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
396 return TRUE;
397 }
398
399 /*
400 ** Check to see if the RTA is configured for this host
401 */
402 for ( ThisUnit=0; ThisUnit<MAX_RUP; ThisUnit++ )
403 {
404 rio_dprintk (RIO_DEBUG_ROUTE, "Entry %d Flags=%s %s UniqueNum=0x%x\n",
405 ThisUnit,
406 HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE ?
407 "Slot-In-Use":"Not In Use",
408 HostP->Mapping[ThisUnit].Flags & SLOT_TENTATIVE ?
409 "Slot-Tentative":"Not Tentative",
410 HostP->Mapping[ThisUnit].RtaUniqueNum);
411
412 /*
413 ** We have an entry for it.
414 */
415 if ( (HostP->Mapping[ThisUnit].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) &&
416 (HostP->Mapping[ThisUnit].RtaUniqueNum == RtaUniq) )
417 {
418 if (RtaType == TYPE_RTA16)
419 {
420 ThisUnit2 = HostP->Mapping[ThisUnit].ID2 - 1;
421 rio_dprintk (RIO_DEBUG_ROUTE, "Found unit 0x%x at slots %d+%d\n",
422 RtaUniq,ThisUnit,ThisUnit2);
423 }
424 else
425 rio_dprintk (RIO_DEBUG_ROUTE, "Found unit 0x%x at slot %d\n",
426 RtaUniq,ThisUnit);
427 /*
428 ** If we have no knowledge of booting it, then the host has
429 ** been re-booted, and so we must kill the RTA, so that it
430 ** will be booted again (potentially with new bins)
431 ** and it will then re-ask for an ID, which we will service.
432 */
433 if ( (HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) &&
434 !(HostP->Mapping[ThisUnit].Flags & RTA_BOOTED) )
435 {
436 if ( !(HostP->Mapping[ThisUnit].Flags & MSG_DONE) )
437 {
438 if ( !p->RIONoMessage )
439 cprintf("RTA '%s' is being updated.\n",HostP->Mapping[ThisUnit].Name);
440 HostP->Mapping[ThisUnit].Flags |= MSG_DONE;
441 } 279 }
442 PktReplyP->Command = ROUTE_FOAD; 280
443 HostP->Copy("RT_FOAD",PktReplyP->CommandText,7); 281 RtaUniq = (RBYTE(PktCmdP->UniqNum[0])) + (RBYTE(PktCmdP->UniqNum[1]) << 8) + (RBYTE(PktCmdP->UniqNum[2]) << 16) + (RBYTE(PktCmdP->UniqNum[3]) << 24);
444 RIOQueueCmdBlk(HostP, Rup, CmdBlkP); 282
445 return TRUE;
446 }
447
448 /*
449 ** Send the ID (entry) to this RTA. The ID number is implicit as
450 ** the offset into the table. It is worth noting at this stage
451 ** that offset zero in the table contains the entries for the
452 ** RTA with ID 1!!!!
453 */
454 PktReplyP->Command = ROUTE_ALLOCATE;
455 PktReplyP->IDNum = ThisUnit+1;
456 if (RtaType == TYPE_RTA16)
457 {
458 if (HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE)
459 /*
460 ** Adjust the phb and tx pkt dest_units for 2nd block of 8
461 ** only if the RTA has ports associated (SLOT_IN_USE)
462 */
463 RIOFixPhbs(p, HostP, ThisUnit2);
464 PktReplyP->IDNum2 = ThisUnit2+1;
465 rio_dprintk (RIO_DEBUG_ROUTE, "RTA '%s' has been allocated IDs %d+%d\n",
466 HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2);
467 }
468 else
469 {
470 PktReplyP->IDNum2 = ROUTE_NO_ID;
471 rio_dprintk (RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n",
472 HostP->Mapping[ThisUnit].Name,PktReplyP->IDNum);
473 }
474 HostP->Copy("RT_ALLOCAT",PktReplyP->CommandText,10);
475
476 RIOQueueCmdBlk( HostP, Rup, CmdBlkP);
477
478 /*
479 ** If this is a freshly booted RTA, then we need to re-open
480 ** the ports, if any where open, so that data may once more
481 ** flow around the system!
482 */
483 if ( (HostP->Mapping[ThisUnit].Flags & RTA_NEWBOOT) &&
484 (HostP->Mapping[ThisUnit].SysPort != NO_PORT) )
485 {
486 /* 283 /*
487 ** look at the ports associated with this beast and 284 ** Determine if 8 or 16 port RTA
488 ** see if any where open. If they was, then re-open 285 */
489 ** them, using the info from the tty flags. 286 RtaType = GetUnitType(RtaUniq);
490 */ 287
491 for ( port=0; port<PORTS_PER_RTA; port++ ) 288 rio_dprintk(RIO_DEBUG_ROUTE, "Received a request for an ID for serial number %x\n", RtaUniq);
492 { 289
493 PortP = p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort]; 290 Mod = RBYTE(PktCmdP->ModuleTypes);
494 if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) ) 291 Mod1 = LONYBLE(Mod);
495 { 292 if (RtaType == TYPE_RTA16) {
496 rio_dprintk (RIO_DEBUG_ROUTE, "Re-opened this port\n"); 293 /*
497 rio_spin_lock_irqsave(&PortP->portSem, flags); 294 ** Only one ident is set for a 16 port RTA. To make compatible
498 PortP->MagicFlags |= MAGIC_REBOOT; 295 ** with 8 port, set 2nd ident in Mod2 to the same as Mod1.
499 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 296 */
500 } 297 Mod2 = Mod1;
298 rio_dprintk(RIO_DEBUG_ROUTE, "Backplane type is %s (all ports)\n", p->RIOModuleTypes[Mod1].Name);
299 } else {
300 Mod2 = HINYBLE(Mod);
301 rio_dprintk(RIO_DEBUG_ROUTE, "Module types are %s (ports 0-3) and %s (ports 4-7)\n", p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name);
501 } 302 }
502 if (RtaType == TYPE_RTA16) 303
503 { 304 if (RtaUniq == 0xffffffff) {
504 for ( port=0; port<PORTS_PER_RTA; port++ ) 305 ShowPacket(DBG_SPECIAL, PacketP);
505 {
506 PortP = p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort];
507 if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) )
508 {
509 rio_dprintk (RIO_DEBUG_ROUTE, "Re-opened this port\n");
510 rio_spin_lock_irqsave(&PortP->portSem, flags);
511 PortP->MagicFlags |= MAGIC_REBOOT;
512 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
513 }
514 }
515 } 306 }
516 } 307
517 308 /*
518 /* 309 ** try to unhook a command block from the command free list.
519 ** keep a copy of the module types! 310 */
520 */ 311 if (!(CmdBlkP = RIOGetCmdBlk())) {
521 HostP->UnixRups[ThisUnit].ModTypes = Mod; 312 rio_dprintk(RIO_DEBUG_ROUTE, "No command blocks to route RTA! come back later.\n");
522 if (RtaType == TYPE_RTA16) 313 return 0;
523 HostP->UnixRups[ThisUnit2].ModTypes = Mod;
524
525 /*
526 ** If either of the modules on this unit is read-only or write-only
527 ** or none-xprint, then we need to transfer that info over to the
528 ** relevant ports.
529 */
530 if ( HostP->Mapping[ThisUnit].SysPort != NO_PORT )
531 {
532 for ( port=0; port<PORTS_PER_MODULE; port++ )
533 {
534 p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK;
535 p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort]->Config |=
536 p->RIOModuleTypes[Mod1].Flags[port];
537 p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK;
538 p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port];
539 } 314 }
540 if (RtaType == TYPE_RTA16) 315
541 { 316 /*
542 for ( port=0; port<PORTS_PER_MODULE; port++ ) 317 ** Fill in the default info on the command block
543 { 318 */
544 p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK; 319 CmdBlkP->Packet.dest_unit = Rup;
545 p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port]; 320 CmdBlkP->Packet.dest_port = ROUTE_RUP;
546 p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK; 321 CmdBlkP->Packet.src_unit = HOST_ID;
547 p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port]; 322 CmdBlkP->Packet.src_port = ROUTE_RUP;
548 } 323 CmdBlkP->Packet.len = PKT_CMD_BIT | 1;
324 CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL;
325 PktReplyP = (struct PktCmd_M *) CmdBlkP->Packet.data;
326
327 if (!RIOBootOk(p, HostP, RtaUniq)) {
328 rio_dprintk(RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n", RtaUniq);
329 PktReplyP->Command = ROUTE_FOAD;
330 HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7);
331 RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
332 return TRUE;
549 } 333 }
550 } 334
551 335 /*
552 /* 336 ** Check to see if the RTA is configured for this host
553 ** Job done, get on with the interrupts! 337 */
554 */ 338 for (ThisUnit = 0; ThisUnit < MAX_RUP; ThisUnit++) {
555 return TRUE; 339 rio_dprintk(RIO_DEBUG_ROUTE, "Entry %d Flags=%s %s UniqueNum=0x%x\n",
556 } 340 ThisUnit, HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE ? "Slot-In-Use" : "Not In Use", HostP->Mapping[ThisUnit].Flags & SLOT_TENTATIVE ? "Slot-Tentative" : "Not Tentative", HostP->Mapping[ThisUnit].RtaUniqueNum);
557 } 341
558 /* 342 /*
559 ** There is no table entry for this RTA at all. 343 ** We have an entry for it.
560 ** 344 */
561 ** Lets check to see if we actually booted this unit - if not, 345 if ((HostP->Mapping[ThisUnit].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) && (HostP->Mapping[ThisUnit].RtaUniqueNum == RtaUniq)) {
562 ** then we reset it and it will go round the loop of being booted 346 if (RtaType == TYPE_RTA16) {
563 ** we can then worry about trying to fit it into the table. 347 ThisUnit2 = HostP->Mapping[ThisUnit].ID2 - 1;
564 */ 348 rio_dprintk(RIO_DEBUG_ROUTE, "Found unit 0x%x at slots %d+%d\n", RtaUniq, ThisUnit, ThisUnit2);
565 for ( ThisUnit=0; ThisUnit<HostP->NumExtraBooted; ThisUnit++ ) 349 } else
566 if ( HostP->ExtraUnits[ThisUnit] == RtaUniq ) 350 rio_dprintk(RIO_DEBUG_ROUTE, "Found unit 0x%x at slot %d\n", RtaUniq, ThisUnit);
567 break; 351 /*
568 if ( ThisUnit == HostP->NumExtraBooted && ThisUnit != MAX_EXTRA_UNITS ) 352 ** If we have no knowledge of booting it, then the host has
569 { 353 ** been re-booted, and so we must kill the RTA, so that it
570 /* 354 ** will be booted again (potentially with new bins)
571 ** if the unit wasn't in the table, and the table wasn't full, then 355 ** and it will then re-ask for an ID, which we will service.
572 ** we reset the unit, because we didn't boot it. 356 */
573 ** However, if the table is full, it could be that we did boot 357 if ((HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) && !(HostP->Mapping[ThisUnit].Flags & RTA_BOOTED)) {
574 ** this unit, and so we won't reboot it, because it isn't really 358 if (!(HostP->Mapping[ThisUnit].Flags & MSG_DONE)) {
575 ** all that disasterous to keep the old bins in most cases. This 359 if (!p->RIONoMessage)
576 ** is a rather tacky feature, but we are on the edge of reallity 360 cprintf("RTA '%s' is being updated.\n", HostP->Mapping[ThisUnit].Name);
577 ** here, because the implication is that someone has connected 361 HostP->Mapping[ThisUnit].Flags |= MSG_DONE;
578 ** 16+MAX_EXTRA_UNITS onto one host. 362 }
579 */ 363 PktReplyP->Command = ROUTE_FOAD;
580 static int UnknownMesgDone = 0; 364 HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7);
581 365 RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
582 if ( !UnknownMesgDone ) 366 return TRUE;
583 { 367 }
584 if (! p->RIONoMessage) 368
585 cprintf("One or more unknown RTAs are being updated.\n"); 369 /*
586 UnknownMesgDone = 1; 370 ** Send the ID (entry) to this RTA. The ID number is implicit as
587 } 371 ** the offset into the table. It is worth noting at this stage
588 372 ** that offset zero in the table contains the entries for the
589 PktReplyP->Command = ROUTE_FOAD; 373 ** RTA with ID 1!!!!
590 HostP->Copy("RT_FOAD",PktReplyP->CommandText,7); 374 */
591 } 375 PktReplyP->Command = ROUTE_ALLOCATE;
592 else 376 PktReplyP->IDNum = ThisUnit + 1;
593 { 377 if (RtaType == TYPE_RTA16) {
594 /* 378 if (HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE)
595 ** we did boot it (as an extra), and there may now be a table 379 /*
596 ** slot free (because of a delete), so we will try to make 380 ** Adjust the phb and tx pkt dest_units for 2nd block of 8
597 ** a tentative entry for it, so that the configurator can see it 381 ** only if the RTA has ports associated (SLOT_IN_USE)
598 ** and fill in the details for us. 382 */
599 */ 383 RIOFixPhbs(p, HostP, ThisUnit2);
600 if (RtaType == TYPE_RTA16) 384 PktReplyP->IDNum2 = ThisUnit2 + 1;
601 { 385 rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated IDs %d+%d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2);
602 if (RIOFindFreeID(p, HostP, &ThisUnit, &ThisUnit2) == 0) 386 } else {
603 { 387 PktReplyP->IDNum2 = ROUTE_NO_ID;
604 RIODefaultName(p, HostP, ThisUnit); 388 rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum);
605 FillSlot(ThisUnit, ThisUnit2, RtaUniq, HostP); 389 }
390 HostP->Copy("RT_ALLOCAT", PktReplyP->CommandText, 10);
391
392 RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
393
394 /*
395 ** If this is a freshly booted RTA, then we need to re-open
396 ** the ports, if any where open, so that data may once more
397 ** flow around the system!
398 */
399 if ((HostP->Mapping[ThisUnit].Flags & RTA_NEWBOOT) && (HostP->Mapping[ThisUnit].SysPort != NO_PORT)) {
400 /*
401 ** look at the ports associated with this beast and
402 ** see if any where open. If they was, then re-open
403 ** them, using the info from the tty flags.
404 */
405 for (port = 0; port < PORTS_PER_RTA; port++) {
406 PortP = p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort];
407 if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) {
408 rio_dprintk(RIO_DEBUG_ROUTE, "Re-opened this port\n");
409 rio_spin_lock_irqsave(&PortP->portSem, flags);
410 PortP->MagicFlags |= MAGIC_REBOOT;
411 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
412 }
413 }
414 if (RtaType == TYPE_RTA16) {
415 for (port = 0; port < PORTS_PER_RTA; port++) {
416 PortP = p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort];
417 if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) {
418 rio_dprintk(RIO_DEBUG_ROUTE, "Re-opened this port\n");
419 rio_spin_lock_irqsave(&PortP->portSem, flags);
420 PortP->MagicFlags |= MAGIC_REBOOT;
421 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
422 }
423 }
424 }
425 }
426
427 /*
428 ** keep a copy of the module types!
429 */
430 HostP->UnixRups[ThisUnit].ModTypes = Mod;
431 if (RtaType == TYPE_RTA16)
432 HostP->UnixRups[ThisUnit2].ModTypes = Mod;
433
434 /*
435 ** If either of the modules on this unit is read-only or write-only
436 ** or none-xprint, then we need to transfer that info over to the
437 ** relevant ports.
438 */
439 if (HostP->Mapping[ThisUnit].SysPort != NO_PORT) {
440 for (port = 0; port < PORTS_PER_MODULE; port++) {
441 p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK;
442 p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port];
443 p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK;
444 p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port];
445 }
446 if (RtaType == TYPE_RTA16) {
447 for (port = 0; port < PORTS_PER_MODULE; port++) {
448 p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK;
449 p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port];
450 p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK;
451 p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port];
452 }
453 }
454 }
455
456 /*
457 ** Job done, get on with the interrupts!
458 */
459 return TRUE;
460 }
606 } 461 }
607 } 462 /*
608 else 463 ** There is no table entry for this RTA at all.
609 { 464 **
610 if (RIOFindFreeID(p, HostP, &ThisUnit, NULL) == 0) 465 ** Lets check to see if we actually booted this unit - if not,
611 { 466 ** then we reset it and it will go round the loop of being booted
612 RIODefaultName(p, HostP, ThisUnit); 467 ** we can then worry about trying to fit it into the table.
613 FillSlot(ThisUnit, 0, RtaUniq, HostP); 468 */
469 for (ThisUnit = 0; ThisUnit < HostP->NumExtraBooted; ThisUnit++)
470 if (HostP->ExtraUnits[ThisUnit] == RtaUniq)
471 break;
472 if (ThisUnit == HostP->NumExtraBooted && ThisUnit != MAX_EXTRA_UNITS) {
473 /*
474 ** if the unit wasn't in the table, and the table wasn't full, then
475 ** we reset the unit, because we didn't boot it.
476 ** However, if the table is full, it could be that we did boot
477 ** this unit, and so we won't reboot it, because it isn't really
478 ** all that disasterous to keep the old bins in most cases. This
479 ** is a rather tacky feature, but we are on the edge of reallity
480 ** here, because the implication is that someone has connected
481 ** 16+MAX_EXTRA_UNITS onto one host.
482 */
483 static int UnknownMesgDone = 0;
484
485 if (!UnknownMesgDone) {
486 if (!p->RIONoMessage)
487 cprintf("One or more unknown RTAs are being updated.\n");
488 UnknownMesgDone = 1;
489 }
490
491 PktReplyP->Command = ROUTE_FOAD;
492 HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7);
493 } else {
494 /*
495 ** we did boot it (as an extra), and there may now be a table
496 ** slot free (because of a delete), so we will try to make
497 ** a tentative entry for it, so that the configurator can see it
498 ** and fill in the details for us.
499 */
500 if (RtaType == TYPE_RTA16) {
501 if (RIOFindFreeID(p, HostP, &ThisUnit, &ThisUnit2) == 0) {
502 RIODefaultName(p, HostP, ThisUnit);
503 FillSlot(ThisUnit, ThisUnit2, RtaUniq, HostP);
504 }
505 } else {
506 if (RIOFindFreeID(p, HostP, &ThisUnit, NULL) == 0) {
507 RIODefaultName(p, HostP, ThisUnit);
508 FillSlot(ThisUnit, 0, RtaUniq, HostP);
509 }
510 }
511 PktReplyP->Command = ROUTE_USED;
512 HostP->Copy("RT_USED", PktReplyP->CommandText, 7);
614 } 513 }
615 } 514 RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
616 PktReplyP->Command = ROUTE_USED; 515 return TRUE;
617 HostP->Copy("RT_USED",PktReplyP->CommandText,7);
618 }
619 RIOQueueCmdBlk( HostP, Rup, CmdBlkP);
620 return TRUE;
621} 516}
622 517
623 518
624void 519void RIOFixPhbs(p, HostP, unit)
625RIOFixPhbs(p, HostP, unit)
626struct rio_info *p; 520struct rio_info *p;
627struct Host *HostP; 521struct Host *HostP;
628uint unit; 522uint unit;
629{ 523{
630 ushort link, port; 524 ushort link, port;
631 struct Port *PortP; 525 struct Port *PortP;
632 unsigned long flags; 526 unsigned long flags;
633 int PortN = HostP->Mapping[unit].SysPort; 527 int PortN = HostP->Mapping[unit].SysPort;
634 528
635 rio_dprintk (RIO_DEBUG_ROUTE, "RIOFixPhbs unit %d sysport %d\n", unit, PortN); 529 rio_dprintk(RIO_DEBUG_ROUTE, "RIOFixPhbs unit %d sysport %d\n", unit, PortN);
636 530
637 if (PortN != -1) { 531 if (PortN != -1) {
638 ushort dest_unit = HostP->Mapping[unit].ID2; 532 ushort dest_unit = HostP->Mapping[unit].ID2;
639 533
640 /* 534 /*
641 ** Get the link number used for the 1st 8 phbs on this unit. 535 ** Get the link number used for the 1st 8 phbs on this unit.
642 */ 536 */
643 PortP = p->RIOPortp[HostP->Mapping[dest_unit - 1].SysPort]; 537 PortP = p->RIOPortp[HostP->Mapping[dest_unit - 1].SysPort];
644 538
645 link = RWORD(PortP->PhbP->link); 539 link = RWORD(PortP->PhbP->link);
646 540
647 for (port = 0; port < PORTS_PER_RTA; port++, PortN++) { 541 for (port = 0; port < PORTS_PER_RTA; port++, PortN++) {
648 ushort dest_port = port + 8; 542 ushort dest_port = port + 8;
649#if 0 543#if 0
650 uint PktInt; 544 uint PktInt;
651#endif 545#endif
652 WORD *TxPktP; 546 WORD *TxPktP;
653 PKT *Pkt; 547 PKT *Pkt;
654 548
655 PortP = p->RIOPortp[PortN]; 549 PortP = p->RIOPortp[PortN];
656 550
657 rio_spin_lock_irqsave(&PortP->portSem, flags); 551 rio_spin_lock_irqsave(&PortP->portSem, flags);
658 /* 552 /*
659 ** If RTA is not powered on, the tx packets will be 553 ** If RTA is not powered on, the tx packets will be
660 ** unset, so go no further. 554 ** unset, so go no further.
661 */ 555 */
662 if (PortP->TxStart == 0) { 556 if (PortP->TxStart == 0) {
663 rio_dprintk (RIO_DEBUG_ROUTE, "Tx pkts not set up yet\n"); 557 rio_dprintk(RIO_DEBUG_ROUTE, "Tx pkts not set up yet\n");
664 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 558 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
665 break; 559 break;
666 } 560 }
667 561
668 /* 562 /*
669 ** For the second slot of a 16 port RTA, the driver needs to 563 ** For the second slot of a 16 port RTA, the driver needs to
670 ** sort out the phb to port mappings. The dest_unit for this 564 ** sort out the phb to port mappings. The dest_unit for this
671 ** group of 8 phbs is set to the dest_unit of the accompanying 565 ** group of 8 phbs is set to the dest_unit of the accompanying
672 ** 8 port block. The dest_port of the second unit is set to 566 ** 8 port block. The dest_port of the second unit is set to
673 ** be in the range 8-15 (i.e. 8 is added). Thus, for a 16 port 567 ** be in the range 8-15 (i.e. 8 is added). Thus, for a 16 port
674 ** RTA with IDs 5 and 6, traffic bound for port 6 of unit 6 568 ** RTA with IDs 5 and 6, traffic bound for port 6 of unit 6
675 ** (being the second map ID) will be sent to dest_unit 5, port 569 ** (being the second map ID) will be sent to dest_unit 5, port
676 ** 14. When this RTA is deleted, dest_unit for ID 6 will be 570 ** 14. When this RTA is deleted, dest_unit for ID 6 will be
677 ** restored, and the dest_port will be reduced by 8. 571 ** restored, and the dest_port will be reduced by 8.
678 ** Transmit packets also have a destination field which needs 572 ** Transmit packets also have a destination field which needs
679 ** adjusting in the same manner. 573 ** adjusting in the same manner.
680 ** Note that the unit/port bytes in 'dest' are swapped. 574 ** Note that the unit/port bytes in 'dest' are swapped.
681 ** We also need to adjust the phb and rup link numbers for the 575 ** We also need to adjust the phb and rup link numbers for the
682 ** second block of 8 ttys. 576 ** second block of 8 ttys.
683 */ 577 */
684 for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) { 578 for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) {
685 /* 579 /*
686 ** *TxPktP is the pointer to the transmit packet on the host 580 ** *TxPktP is the pointer to the transmit packet on the host
687 ** card. This needs to be translated into a 32 bit pointer 581 ** card. This needs to be translated into a 32 bit pointer
688 ** so it can be accessed from the driver. 582 ** so it can be accessed from the driver.
689 */ 583 */
690 Pkt = (PKT *) RIO_PTR(HostP->Caddr,RINDW(TxPktP)); 584 Pkt = (PKT *) RIO_PTR(HostP->Caddr, RINDW(TxPktP));
691 585
692 /* 586 /*
693 ** If the packet is used, reset it. 587 ** If the packet is used, reset it.
694 */ 588 */
695 Pkt = (PKT *)((uint)Pkt & ~PKT_IN_USE); 589 Pkt = (PKT *) ((uint) Pkt & ~PKT_IN_USE);
696 WBYTE(Pkt->dest_unit, dest_unit); 590 WBYTE(Pkt->dest_unit, dest_unit);
697 WBYTE(Pkt->dest_port, dest_port); 591 WBYTE(Pkt->dest_port, dest_port);
698 } 592 }
699 rio_dprintk (RIO_DEBUG_ROUTE, "phb dest: Old %x:%x New %x:%x\n", 593 rio_dprintk(RIO_DEBUG_ROUTE, "phb dest: Old %x:%x New %x:%x\n", RWORD(PortP->PhbP->destination) & 0xff, (RWORD(PortP->PhbP->destination) >> 8) & 0xff, dest_unit, dest_port);
700 RWORD(PortP->PhbP->destination) & 0xff,
701 (RWORD(PortP->PhbP->destination) >> 8) & 0xff,
702 dest_unit, dest_port);
703 WWORD(PortP->PhbP->destination, dest_unit + (dest_port << 8)); 594 WWORD(PortP->PhbP->destination, dest_unit + (dest_port << 8));
704 WWORD(PortP->PhbP->link, link); 595 WWORD(PortP->PhbP->link, link);
705 596
706 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 597 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
707 } 598 }
708 /* 599 /*
709 ** Now make sure the range of ports to be serviced includes 600 ** Now make sure the range of ports to be serviced includes
710 ** the 2nd 8 on this 16 port RTA. 601 ** the 2nd 8 on this 16 port RTA.
711 */ 602 */
712 if (link > 3) return; 603 if (link > 3)
604 return;
713 if (((unit * 8) + 7) > RWORD(HostP->LinkStrP[link].last_port)) { 605 if (((unit * 8) + 7) > RWORD(HostP->LinkStrP[link].last_port)) {
714 rio_dprintk (RIO_DEBUG_ROUTE, "last port on host link %d: %d\n", link, (unit * 8) + 7); 606 rio_dprintk(RIO_DEBUG_ROUTE, "last port on host link %d: %d\n", link, (unit * 8) + 7);
715 WWORD(HostP->LinkStrP[link].last_port, (unit * 8) + 7); 607 WWORD(HostP->LinkStrP[link].last_port, (unit * 8) + 7);
716 } 608 }
717 } 609 }
@@ -723,9 +615,8 @@ uint unit;
723** the world about it. This is done to ensure that the configurator 615** the world about it. This is done to ensure that the configurator
724** only gets up-to-date information about what is going on. 616** only gets up-to-date information about what is going on.
725*/ 617*/
726static int 618static int RIOCheckIsolated(p, HostP, UnitId)
727RIOCheckIsolated(p, HostP, UnitId) 619struct rio_info *p;
728struct rio_info * p;
729struct Host *HostP; 620struct Host *HostP;
730uint UnitId; 621uint UnitId;
731{ 622{
@@ -733,16 +624,16 @@ uint UnitId;
733 rio_spin_lock_irqsave(&HostP->HostLock, flags); 624 rio_spin_lock_irqsave(&HostP->HostLock, flags);
734 625
735#ifdef CHECK 626#ifdef CHECK
736 CheckHostP( HostP ); 627 CheckHostP(HostP);
737 CheckUnitId( UnitId ); 628 CheckUnitId(UnitId);
738#endif 629#endif
739 if ( RIOCheck( HostP, UnitId ) ) { 630 if (RIOCheck(HostP, UnitId)) {
740 rio_dprintk (RIO_DEBUG_ROUTE, "Unit %d is NOT isolated\n", UnitId); 631 rio_dprintk(RIO_DEBUG_ROUTE, "Unit %d is NOT isolated\n", UnitId);
741 rio_spin_unlock_irqrestore(&HostP->HostLock, flags); 632 rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
742 return(0); 633 return (0);
743 } 634 }
744 635
745 RIOIsolate(p, HostP, UnitId ); 636 RIOIsolate(p, HostP, UnitId);
746 RIOSetChange(p); 637 RIOSetChange(p);
747 rio_spin_unlock_irqrestore(&HostP->HostLock, flags); 638 rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
748 return 1; 639 return 1;
@@ -753,85 +644,83 @@ uint UnitId;
753** all the units attached to it. This will mean that the entire 644** all the units attached to it. This will mean that the entire
754** subnet will re-introduce itself. 645** subnet will re-introduce itself.
755*/ 646*/
756static int 647static int RIOIsolate(p, HostP, UnitId)
757RIOIsolate(p, HostP, UnitId) 648struct rio_info *p;
758struct rio_info * p; 649struct Host *HostP;
759struct Host * HostP; 650uint UnitId;
760uint UnitId;
761{ 651{
762 uint link, unit; 652 uint link, unit;
763 653
764#ifdef CHECK 654#ifdef CHECK
765 CheckHostP( HostP ); 655 CheckHostP(HostP);
766 CheckUnitId( UnitId ); 656 CheckUnitId(UnitId);
767#endif 657#endif
768 UnitId--; /* this trick relies on the Unit Id being UNSIGNED! */ 658 UnitId--; /* this trick relies on the Unit Id being UNSIGNED! */
769 659
770 if ( UnitId >= MAX_RUP ) /* dontcha just lurv unsigned maths! */ 660 if (UnitId >= MAX_RUP) /* dontcha just lurv unsigned maths! */
771 return(0); 661 return (0);
772 662
773 if ( HostP->Mapping[UnitId].Flags & BEEN_HERE ) 663 if (HostP->Mapping[UnitId].Flags & BEEN_HERE)
774 return(0); 664 return (0);
775 665
776 HostP->Mapping[UnitId].Flags |= BEEN_HERE; 666 HostP->Mapping[UnitId].Flags |= BEEN_HERE;
777 667
778 if ( p->RIOPrintDisabled == DO_PRINT ) 668 if (p->RIOPrintDisabled == DO_PRINT)
779 rio_dprintk (RIO_DEBUG_ROUTE, "RIOMesgIsolated %s", HostP->Mapping[UnitId].Name); 669 rio_dprintk(RIO_DEBUG_ROUTE, "RIOMesgIsolated %s", HostP->Mapping[UnitId].Name);
780 670
781 for ( link=0; link<LINKS_PER_UNIT; link++) { 671 for (link = 0; link < LINKS_PER_UNIT; link++) {
782 unit = HostP->Mapping[UnitId].Topology[link].Unit; 672 unit = HostP->Mapping[UnitId].Topology[link].Unit;
783 HostP->Mapping[UnitId].Topology[link].Unit = ROUTE_DISCONNECT; 673 HostP->Mapping[UnitId].Topology[link].Unit = ROUTE_DISCONNECT;
784 HostP->Mapping[UnitId].Topology[link].Link = NO_LINK; 674 HostP->Mapping[UnitId].Topology[link].Link = NO_LINK;
785 RIOIsolate(p, HostP, unit ); 675 RIOIsolate(p, HostP, unit);
786 } 676 }
787 HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; 677 HostP->Mapping[UnitId].Flags &= ~BEEN_HERE;
788 return 1; 678 return 1;
789} 679}
790 680
791static int 681static int RIOCheck(HostP, UnitId)
792RIOCheck(HostP, UnitId)
793struct Host *HostP; 682struct Host *HostP;
794uint UnitId; 683uint UnitId;
795{ 684{
796 unsigned char link; 685 unsigned char link;
797 686
798#ifdef CHECK 687#ifdef CHECK
799 CheckHostP( HostP ); 688 CheckHostP(HostP);
800 CheckUnitId( UnitId ); 689 CheckUnitId(UnitId);
801#endif 690#endif
802/* rio_dprint(RIO_DEBUG_ROUTE, ("Check to see if unit %d has a route to the host\n",UnitId)); */ 691/* rio_dprint(RIO_DEBUG_ROUTE, ("Check to see if unit %d has a route to the host\n",UnitId)); */
803 rio_dprintk (RIO_DEBUG_ROUTE, "RIOCheck : UnitID = %d\n", UnitId); 692 rio_dprintk(RIO_DEBUG_ROUTE, "RIOCheck : UnitID = %d\n", UnitId);
804 693
805 if ( UnitId == HOST_ID ) { 694 if (UnitId == HOST_ID) {
806 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated - it IS the host!\n", UnitId)); */ 695 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated - it IS the host!\n", UnitId)); */
807 return 1; 696 return 1;
808 } 697 }
809 698
810 UnitId--; 699 UnitId--;
811 700
812 if ( UnitId >= MAX_RUP ) { 701 if (UnitId >= MAX_RUP) {
813 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d - ignored.\n", UnitId)); */ 702 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d - ignored.\n", UnitId)); */
814 return 0; 703 return 0;
815 } 704 }
816 705
817 for ( link=0; link<LINKS_PER_UNIT; link++ ) { 706 for (link = 0; link < LINKS_PER_UNIT; link++) {
818 if ( HostP->Mapping[UnitId].Topology[link].Unit==HOST_ID ) { 707 if (HostP->Mapping[UnitId].Topology[link].Unit == HOST_ID) {
819 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected directly to host via link (%c).\n", 708 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected directly to host via link (%c).\n",
820 UnitId, 'A'+link)); */ 709 UnitId, 'A'+link)); */
821 return 1; 710 return 1;
822 } 711 }
823 } 712 }
824 713
825 if ( HostP->Mapping[UnitId].Flags & BEEN_HERE ) { 714 if (HostP->Mapping[UnitId].Flags & BEEN_HERE) {
826 /* rio_dprint(RIO_DEBUG_ROUTE, ("Been to Unit %d before - ignoring\n", UnitId)); */ 715 /* rio_dprint(RIO_DEBUG_ROUTE, ("Been to Unit %d before - ignoring\n", UnitId)); */
827 return 0; 716 return 0;
828 } 717 }
829 718
830 HostP->Mapping[UnitId].Flags |= BEEN_HERE; 719 HostP->Mapping[UnitId].Flags |= BEEN_HERE;
831 720
832 for ( link=0; link < LINKS_PER_UNIT; link++ ) { 721 for (link = 0; link < LINKS_PER_UNIT; link++) {
833 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d check link (%c)\n", UnitId,'A'+link)); */ 722 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d check link (%c)\n", UnitId,'A'+link)); */
834 if ( RIOCheck( HostP, HostP->Mapping[UnitId].Topology[link].Unit ) ) { 723 if (RIOCheck(HostP, HostP->Mapping[UnitId].Topology[link].Unit)) {
835 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected to something that knows the host via link (%c)\n", UnitId,link+'A')); */ 724 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected to something that knows the host via link (%c)\n", UnitId,link+'A')); */
836 HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; 725 HostP->Mapping[UnitId].Flags &= ~BEEN_HERE;
837 return 1; 726 return 1;
@@ -841,7 +730,7 @@ uint UnitId;
841 HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; 730 HostP->Mapping[UnitId].Flags &= ~BEEN_HERE;
842 731
843 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d DOESNT KNOW THE HOST!\n", UnitId)); */ 732 /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d DOESNT KNOW THE HOST!\n", UnitId)); */
844 733
845 return 0; 734 return 0;
846} 735}
847 736
@@ -849,61 +738,57 @@ uint UnitId;
849** Returns the type of unit (host, 16/8 port RTA) 738** Returns the type of unit (host, 16/8 port RTA)
850*/ 739*/
851 740
852uint 741uint GetUnitType(Uniq)
853GetUnitType(Uniq)
854uint Uniq; 742uint Uniq;
855{ 743{
856 switch ( (Uniq >> 28) & 0xf) 744 switch ((Uniq >> 28) & 0xf) {
857 { 745 case RIO_AT:
858 case RIO_AT: 746 case RIO_MCA:
859 case RIO_MCA: 747 case RIO_EISA:
860 case RIO_EISA: 748 case RIO_PCI:
861 case RIO_PCI: 749 rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: Host\n");
862 rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: Host\n"); 750 return (TYPE_HOST);
863 return(TYPE_HOST); 751 case RIO_RTA_16:
864 case RIO_RTA_16: 752 rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: 16 port RTA\n");
865 rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: 16 port RTA\n"); 753 return (TYPE_RTA16);
866 return(TYPE_RTA16); 754 case RIO_RTA:
867 case RIO_RTA: 755 rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: 8 port RTA\n");
868 rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: 8 port RTA\n"); 756 return (TYPE_RTA8);
869 return(TYPE_RTA8); 757 default:
870 default : 758 rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: Unrecognised\n");
871 rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: Unrecognised\n"); 759 return (99);
872 return(99);
873 } 760 }
874} 761}
875 762
876int 763int RIOSetChange(p)
877RIOSetChange(p) 764struct rio_info *p;
878struct rio_info * p;
879{ 765{
880 if ( p->RIOQuickCheck != NOT_CHANGED ) 766 if (p->RIOQuickCheck != NOT_CHANGED)
881 return(0); 767 return (0);
882 p->RIOQuickCheck = CHANGED; 768 p->RIOQuickCheck = CHANGED;
883 if ( p->RIOSignalProcess ) { 769 if (p->RIOSignalProcess) {
884 rio_dprintk (RIO_DEBUG_ROUTE, "Send SIG-HUP"); 770 rio_dprintk(RIO_DEBUG_ROUTE, "Send SIG-HUP");
885 /* 771 /*
886 psignal( RIOSignalProcess, SIGHUP ); 772 psignal( RIOSignalProcess, SIGHUP );
887 */ 773 */
888 } 774 }
889 return(0); 775 return (0);
890} 776}
891 777
892static void 778static void RIOConCon(p, HostP, FromId, FromLink, ToId, ToLink, Change)
893RIOConCon(p, HostP, FromId, FromLink, ToId, ToLink, Change) 779struct rio_info *p;
894struct rio_info * p;
895struct Host *HostP; 780struct Host *HostP;
896uint FromId; 781uint FromId;
897uint FromLink; 782uint FromLink;
898uint ToId; 783uint ToId;
899uint ToLink; 784uint ToLink;
900int Change; 785int Change;
901{ 786{
902 char *FromName; 787 char *FromName;
903 char *FromType; 788 char *FromType;
904 char *ToName; 789 char *ToName;
905 char *ToType; 790 char *ToType;
906 unsigned int tp; 791 unsigned int tp;
907 792
908/* 793/*
909** 15.10.1998 ARG - ESIL 0759 794** 15.10.1998 ARG - ESIL 0759
@@ -932,38 +817,32 @@ int Change;
932** rio_info struct - RIORtaDisCons (RIO RTA connections) keeps track of RTA 817** rio_info struct - RIORtaDisCons (RIO RTA connections) keeps track of RTA
933** connections and disconnections. 818** connections and disconnections.
934*/ 819*/
935 if (Change == CONNECT) { 820 if (Change == CONNECT) {
936 if (p->RIORtaDisCons) p->RIORtaDisCons--; 821 if (p->RIORtaDisCons)
937 } 822 p->RIORtaDisCons--;
938 else { 823 } else {
939 p->RIORtaDisCons++; 824 p->RIORtaDisCons++;
940 } 825 }
941 826
942 if ( p->RIOPrintDisabled == DONT_PRINT ) 827 if (p->RIOPrintDisabled == DONT_PRINT)
943 return; 828 return;
944 829
945 if ( FromId > ToId ) { 830 if (FromId > ToId) {
946 tp = FromId; 831 tp = FromId;
947 FromId = ToId; 832 FromId = ToId;
948 ToId = tp; 833 ToId = tp;
949 tp = FromLink; 834 tp = FromLink;
950 FromLink = ToLink; 835 FromLink = ToLink;
951 ToLink = tp; 836 ToLink = tp;
952 } 837 }
953 838
954 FromName = FromId ? HostP->Mapping[FromId-1].Name : HostP->Name; 839 FromName = FromId ? HostP->Mapping[FromId - 1].Name : HostP->Name;
955 FromType = FromId ? "RTA" : "HOST"; 840 FromType = FromId ? "RTA" : "HOST";
956 ToName = ToId ? HostP->Mapping[ToId-1].Name : HostP->Name; 841 ToName = ToId ? HostP->Mapping[ToId - 1].Name : HostP->Name;
957 ToType = ToId ? "RTA" : "HOST"; 842 ToType = ToId ? "RTA" : "HOST";
958 843
959 rio_dprintk (RIO_DEBUG_ROUTE, "Link between %s '%s' (%c) and %s '%s' (%c) %s.\n", 844 rio_dprintk(RIO_DEBUG_ROUTE, "Link between %s '%s' (%c) and %s '%s' (%c) %s.\n", FromType, FromName, 'A' + FromLink, ToType, ToName, 'A' + ToLink, (Change == CONNECT) ? "established" : "disconnected");
960 FromType, FromName, 'A'+FromLink, 845 cprintf("Link between %s '%s' (%c) and %s '%s' (%c) %s.\n", FromType, FromName, 'A' + FromLink, ToType, ToName, 'A' + ToLink, (Change == CONNECT) ? "established" : "disconnected");
961 ToType, ToName, 'A'+ToLink,
962 (Change==CONNECT) ? "established" : "disconnected");
963 cprintf("Link between %s '%s' (%c) and %s '%s' (%c) %s.\n",
964 FromType, FromName, 'A'+FromLink,
965 ToType, ToName, 'A'+ToLink,
966 (Change==CONNECT) ? "established" : "disconnected");
967} 846}
968 847
969/* 848/*
@@ -972,24 +851,21 @@ int Change;
972** Delete and RTA entry from the saved table given to us 851** Delete and RTA entry from the saved table given to us
973** by the configuration program. 852** by the configuration program.
974*/ 853*/
975static int 854static int RIORemoveFromSavedTable(struct rio_info *p, struct Map *pMap)
976RIORemoveFromSavedTable(struct rio_info *p, struct Map *pMap)
977{ 855{
978 int entry; 856 int entry;
979 857
980 /* 858 /*
981 ** We loop for all entries even after finding an entry and 859 ** We loop for all entries even after finding an entry and
982 ** zeroing it because we may have two entries to delete if 860 ** zeroing it because we may have two entries to delete if
983 ** it's a 16 port RTA. 861 ** it's a 16 port RTA.
984 */ 862 */
985 for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) 863 for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) {
986 { 864 if (p->RIOSavedTable[entry].RtaUniqueNum == pMap->RtaUniqueNum) {
987 if (p->RIOSavedTable[entry].RtaUniqueNum == pMap->RtaUniqueNum) 865 bzero((caddr_t) & p->RIOSavedTable[entry], sizeof(struct Map));
988 { 866 }
989 bzero((caddr_t)&p->RIOSavedTable[entry], sizeof(struct Map));
990 } 867 }
991 } 868 return 0;
992 return 0;
993} 869}
994 870
995 871
@@ -999,64 +875,58 @@ RIORemoveFromSavedTable(struct rio_info *p, struct Map *pMap)
999** Scan the unit links to and return zero if the unit is completely 875** Scan the unit links to and return zero if the unit is completely
1000** disconnected. 876** disconnected.
1001*/ 877*/
1002static int 878static int RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit)
1003RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit)
1004{ 879{
1005 int link; 880 int link;
1006 881
1007 882
1008 rio_dprintk (RIO_DEBUG_ROUTE, "RIOFreeDisconnect unit %d\n", unit); 883 rio_dprintk(RIO_DEBUG_ROUTE, "RIOFreeDisconnect unit %d\n", unit);
1009 /* 884 /*
1010 ** If the slot is tentative and does not belong to the 885 ** If the slot is tentative and does not belong to the
1011 ** second half of a 16 port RTA then scan to see if 886 ** second half of a 16 port RTA then scan to see if
1012 ** is disconnected. 887 ** is disconnected.
1013 */ 888 */
1014 for (link = 0; link < LINKS_PER_UNIT; link++) 889 for (link = 0; link < LINKS_PER_UNIT; link++) {
1015 { 890 if (HostP->Mapping[unit].Topology[link].Unit != ROUTE_DISCONNECT)
1016 if (HostP->Mapping[unit].Topology[link].Unit != ROUTE_DISCONNECT) 891 break;
1017 break; 892 }
1018 } 893
1019 894 /*
1020 /* 895 ** If not all links are disconnected then we can forget about it.
1021 ** If not all links are disconnected then we can forget about it. 896 */
1022 */ 897 if (link < LINKS_PER_UNIT)
1023 if (link < LINKS_PER_UNIT) 898 return 1;
1024 return 1;
1025 899
1026#ifdef NEED_TO_FIX_THIS 900#ifdef NEED_TO_FIX_THIS
1027 /* Ok so all the links are disconnected. But we may have only just 901 /* Ok so all the links are disconnected. But we may have only just
1028 ** made this slot tentative and not yet received a topology update. 902 ** made this slot tentative and not yet received a topology update.
1029 ** Lets check how long ago we made it tentative. 903 ** Lets check how long ago we made it tentative.
1030 */ 904 */
1031 rio_dprintk (RIO_DEBUG_ROUTE, "Just about to check LBOLT on entry %d\n", unit); 905 rio_dprintk(RIO_DEBUG_ROUTE, "Just about to check LBOLT on entry %d\n", unit);
1032 if (drv_getparm(LBOLT, (ulong_t *) &current_time)) 906 if (drv_getparm(LBOLT, (ulong_t *) & current_time))
1033 rio_dprintk (RIO_DEBUG_ROUTE, "drv_getparm(LBOLT,....) Failed.\n"); 907 rio_dprintk(RIO_DEBUG_ROUTE, "drv_getparm(LBOLT,....) Failed.\n");
1034 908
1035 elapse_time = current_time - TentTime[unit]; 909 elapse_time = current_time - TentTime[unit];
1036 rio_dprintk (RIO_DEBUG_ROUTE, "elapse %d = current %d - tent %d (%d usec)\n", 910 rio_dprintk(RIO_DEBUG_ROUTE, "elapse %d = current %d - tent %d (%d usec)\n", elapse_time, current_time, TentTime[unit], drv_hztousec(elapse_time));
1037 elapse_time, current_time, TentTime[unit], drv_hztousec(elapse_time)); 911 if (drv_hztousec(elapse_time) < WAIT_TO_FINISH) {
1038 if (drv_hztousec(elapse_time) < WAIT_TO_FINISH) 912 rio_dprintk(RIO_DEBUG_ROUTE, "Skipping slot %d, not timed out yet %d\n", unit, drv_hztousec(elapse_time));
1039 { 913 return 1;
1040 rio_dprintk (RIO_DEBUG_ROUTE, "Skipping slot %d, not timed out yet %d\n", 914 }
1041 unit, drv_hztousec(elapse_time));
1042 return 1;
1043 }
1044#endif 915#endif
1045 916
1046 /* 917 /*
1047 ** We have found an usable slot. 918 ** We have found an usable slot.
1048 ** If it is half of a 16 port RTA then delete the other half. 919 ** If it is half of a 16 port RTA then delete the other half.
1049 */ 920 */
1050 if (HostP->Mapping[unit].ID2 != 0) 921 if (HostP->Mapping[unit].ID2 != 0) {
1051 { 922 int nOther = (HostP->Mapping[unit].ID2) - 1;
1052 int nOther = (HostP->Mapping[unit].ID2) -1; 923
1053 924 rio_dprintk(RIO_DEBUG_ROUTE, "RioFreedis second slot %d.\n", nOther);
1054 rio_dprintk (RIO_DEBUG_ROUTE, "RioFreedis second slot %d.\n", nOther); 925 bzero((caddr_t) & HostP->Mapping[nOther], sizeof(struct Map));
1055 bzero((caddr_t)&HostP->Mapping[nOther], sizeof(struct Map)); 926 }
1056 } 927 RIORemoveFromSavedTable(p, &HostP->Mapping[unit]);
1057 RIORemoveFromSavedTable(p, &HostP->Mapping[unit]);
1058 928
1059 return 0; 929 return 0;
1060} 930}
1061 931
1062 932
@@ -1066,150 +936,134 @@ RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit)
1066** This function scans the given host table for either one 936** This function scans the given host table for either one
1067** or two free unit ID's. 937** or two free unit ID's.
1068*/ 938*/
1069int 939int RIOFindFreeID(struct rio_info *p, struct Host *HostP, uint * pID1, uint * pID2)
1070RIOFindFreeID(struct rio_info *p, struct Host *HostP, uint *pID1, uint *pID2)
1071{ 940{
1072 int unit,tempID; 941 int unit, tempID;
1073 942
1074 /*
1075 ** Initialise the ID's to MAX_RUP.
1076 ** We do this to make the loop for setting the ID's as simple as
1077 ** possible.
1078 */
1079 *pID1 = MAX_RUP;
1080 if (pID2 != NULL)
1081 *pID2 = MAX_RUP;
1082
1083 /*
1084 ** Scan all entries of the host mapping table for free slots.
1085 ** We scan for free slots first and then if that is not successful
1086 ** we start all over again looking for tentative slots we can re-use.
1087 */
1088 for (unit = 0; unit < MAX_RUP; unit++)
1089 {
1090 rio_dprintk (RIO_DEBUG_ROUTE, "Scanning unit %d\n",unit);
1091 /* 943 /*
1092 ** If the flags are zero then the slot is empty. 944 ** Initialise the ID's to MAX_RUP.
1093 */ 945 ** We do this to make the loop for setting the ID's as simple as
1094 if (HostP->Mapping[unit].Flags == 0) 946 ** possible.
1095 { 947 */
1096 rio_dprintk (RIO_DEBUG_ROUTE, " This slot is empty.\n"); 948 *pID1 = MAX_RUP;
1097 /* 949 if (pID2 != NULL)
1098 ** If we haven't allocated the first ID then do it now. 950 *pID2 = MAX_RUP;
1099 */
1100 if (*pID1 == MAX_RUP)
1101 {
1102 rio_dprintk (RIO_DEBUG_ROUTE, "Make tentative entry for first unit %d\n", unit);
1103 *pID1 = unit;
1104 951
952 /*
953 ** Scan all entries of the host mapping table for free slots.
954 ** We scan for free slots first and then if that is not successful
955 ** we start all over again looking for tentative slots we can re-use.
956 */
957 for (unit = 0; unit < MAX_RUP; unit++) {
958 rio_dprintk(RIO_DEBUG_ROUTE, "Scanning unit %d\n", unit);
1105 /* 959 /*
1106 ** If the second ID is not needed then we can return 960 ** If the flags are zero then the slot is empty.
1107 ** now. 961 */
1108 */ 962 if (HostP->Mapping[unit].Flags == 0) {
1109 if (pID2 == NULL) 963 rio_dprintk(RIO_DEBUG_ROUTE, " This slot is empty.\n");
1110 return 0; 964 /*
1111 } 965 ** If we haven't allocated the first ID then do it now.
1112 else 966 */
1113 { 967 if (*pID1 == MAX_RUP) {
1114 /* 968 rio_dprintk(RIO_DEBUG_ROUTE, "Make tentative entry for first unit %d\n", unit);
1115 ** Allocate the second slot and return. 969 *pID1 = unit;
1116 */ 970
1117 rio_dprintk (RIO_DEBUG_ROUTE, "Make tentative entry for second unit %d\n", unit); 971 /*
1118 *pID2 = unit; 972 ** If the second ID is not needed then we can return
1119 return 0; 973 ** now.
1120 } 974 */
975 if (pID2 == NULL)
976 return 0;
977 } else {
978 /*
979 ** Allocate the second slot and return.
980 */
981 rio_dprintk(RIO_DEBUG_ROUTE, "Make tentative entry for second unit %d\n", unit);
982 *pID2 = unit;
983 return 0;
984 }
985 }
1121 } 986 }
1122 }
1123
1124 /*
1125 ** If we manage to come out of the free slot loop then we
1126 ** need to start all over again looking for tentative slots
1127 ** that we can re-use.
1128 */
1129 rio_dprintk (RIO_DEBUG_ROUTE, "Starting to scan for tentative slots\n");
1130 for (unit = 0; unit < MAX_RUP; unit++)
1131 {
1132 if (((HostP->Mapping[unit].Flags & SLOT_TENTATIVE) ||
1133 (HostP->Mapping[unit].Flags == 0)) && !
1134 (HostP->Mapping[unit].Flags & RTA16_SECOND_SLOT ))
1135 {
1136 rio_dprintk (RIO_DEBUG_ROUTE, " Slot %d looks promising.\n",unit);
1137
1138 if(unit == *pID1)
1139 {
1140 rio_dprintk (RIO_DEBUG_ROUTE, " No it isn't, its the 1st half\n");
1141 continue;
1142 }
1143
1144 /*
1145 ** Slot is Tentative or Empty, but not a tentative second
1146 ** slot of a 16 porter.
1147 ** Attempt to free up this slot (and its parnter if
1148 ** it is a 16 port slot. The second slot will become
1149 ** empty after a call to RIOFreeDisconnected so thats why
1150 ** we look for empty slots above as well).
1151 */
1152 if (HostP->Mapping[unit].Flags != 0)
1153 if (RIOFreeDisconnected(p, HostP, unit) != 0)
1154 continue;
1155 /*
1156 ** If we haven't allocated the first ID then do it now.
1157 */
1158 if (*pID1 == MAX_RUP)
1159 {
1160 rio_dprintk (RIO_DEBUG_ROUTE, "Grab tentative entry for first unit %d\n", unit);
1161 *pID1 = unit;
1162 987
1163 /* 988 /*
1164 ** Clear out this slot now that we intend to use it. 989 ** If we manage to come out of the free slot loop then we
1165 */ 990 ** need to start all over again looking for tentative slots
1166 bzero(&HostP->Mapping[unit], sizeof(struct Map)); 991 ** that we can re-use.
992 */
993 rio_dprintk(RIO_DEBUG_ROUTE, "Starting to scan for tentative slots\n");
994 for (unit = 0; unit < MAX_RUP; unit++) {
995 if (((HostP->Mapping[unit].Flags & SLOT_TENTATIVE) || (HostP->Mapping[unit].Flags == 0)) && !(HostP->Mapping[unit].Flags & RTA16_SECOND_SLOT)) {
996 rio_dprintk(RIO_DEBUG_ROUTE, " Slot %d looks promising.\n", unit);
997
998 if (unit == *pID1) {
999 rio_dprintk(RIO_DEBUG_ROUTE, " No it isn't, its the 1st half\n");
1000 continue;
1001 }
1167 1002
1168 /* 1003 /*
1169 ** If the second ID is not needed then we can return 1004 ** Slot is Tentative or Empty, but not a tentative second
1170 ** now. 1005 ** slot of a 16 porter.
1171 */ 1006 ** Attempt to free up this slot (and its parnter if
1172 if (pID2 == NULL) 1007 ** it is a 16 port slot. The second slot will become
1173 return 0; 1008 ** empty after a call to RIOFreeDisconnected so thats why
1174 } 1009 ** we look for empty slots above as well).
1175 else 1010 */
1176 { 1011 if (HostP->Mapping[unit].Flags != 0)
1177 /* 1012 if (RIOFreeDisconnected(p, HostP, unit) != 0)
1178 ** Allocate the second slot and return. 1013 continue;
1179 */ 1014 /*
1180 rio_dprintk (RIO_DEBUG_ROUTE, "Grab tentative/empty entry for second unit %d\n", 1015 ** If we haven't allocated the first ID then do it now.
1181 unit); 1016 */
1182 *pID2 = unit; 1017 if (*pID1 == MAX_RUP) {
1018 rio_dprintk(RIO_DEBUG_ROUTE, "Grab tentative entry for first unit %d\n", unit);
1019 *pID1 = unit;
1183 1020
1184 /* 1021 /*
1185 ** Clear out this slot now that we intend to use it. 1022 ** Clear out this slot now that we intend to use it.
1186 */ 1023 */
1187 bzero(&HostP->Mapping[unit], sizeof(struct Map)); 1024 bzero(&HostP->Mapping[unit], sizeof(struct Map));
1188 1025
1189 /* At this point under the right(wrong?) conditions 1026 /*
1190 ** we may have a first unit ID being higher than the 1027 ** If the second ID is not needed then we can return
1191 ** second unit ID. This is a bad idea if we are about 1028 ** now.
1192 ** to fill the slots with a 16 port RTA. 1029 */
1193 ** Better check and swap them over. 1030 if (pID2 == NULL)
1194 */ 1031 return 0;
1195 1032 } else {
1196 if (*pID1 > *pID2) 1033 /*
1197 { 1034 ** Allocate the second slot and return.
1198 rio_dprintk (RIO_DEBUG_ROUTE, "Swapping IDS %d %d\n", *pID1, *pID2); 1035 */
1199 tempID = *pID1; 1036 rio_dprintk(RIO_DEBUG_ROUTE, "Grab tentative/empty entry for second unit %d\n", unit);
1200 *pID1 = *pID2; 1037 *pID2 = unit;
1201 *pID2 = tempID; 1038
1039 /*
1040 ** Clear out this slot now that we intend to use it.
1041 */
1042 bzero(&HostP->Mapping[unit], sizeof(struct Map));
1043
1044 /* At this point under the right(wrong?) conditions
1045 ** we may have a first unit ID being higher than the
1046 ** second unit ID. This is a bad idea if we are about
1047 ** to fill the slots with a 16 port RTA.
1048 ** Better check and swap them over.
1049 */
1050
1051 if (*pID1 > *pID2) {
1052 rio_dprintk(RIO_DEBUG_ROUTE, "Swapping IDS %d %d\n", *pID1, *pID2);
1053 tempID = *pID1;
1054 *pID1 = *pID2;
1055 *pID2 = tempID;
1056 }
1057 return 0;
1058 }
1202 } 1059 }
1203 return 0;
1204 }
1205 } 1060 }
1206 }
1207 1061
1208 /* 1062 /*
1209 ** If we manage to get to the end of the second loop then we 1063 ** If we manage to get to the end of the second loop then we
1210 ** can give up and return a failure. 1064 ** can give up and return a failure.
1211 */ 1065 */
1212 return 1; 1066 return 1;
1213} 1067}
1214 1068
1215 1069