diff options
Diffstat (limited to 'drivers/char/rio/rioroute.c')
-rw-r--r-- | drivers/char/rio/rioroute.c | 1572 |
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 | */ |
96 | int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP ) | 96 | int 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 | ||
624 | void | 519 | void RIOFixPhbs(p, HostP, unit) |
625 | RIOFixPhbs(p, HostP, unit) | ||
626 | struct rio_info *p; | 520 | struct rio_info *p; |
627 | struct Host *HostP; | 521 | struct Host *HostP; |
628 | uint unit; | 522 | uint 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 | */ |
726 | static int | 618 | static int RIOCheckIsolated(p, HostP, UnitId) |
727 | RIOCheckIsolated(p, HostP, UnitId) | 619 | struct rio_info *p; |
728 | struct rio_info * p; | ||
729 | struct Host *HostP; | 620 | struct Host *HostP; |
730 | uint UnitId; | 621 | uint 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 | */ |
756 | static int | 647 | static int RIOIsolate(p, HostP, UnitId) |
757 | RIOIsolate(p, HostP, UnitId) | 648 | struct rio_info *p; |
758 | struct rio_info * p; | 649 | struct Host *HostP; |
759 | struct Host * HostP; | 650 | uint UnitId; |
760 | uint 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 | ||
791 | static int | 681 | static int RIOCheck(HostP, UnitId) |
792 | RIOCheck(HostP, UnitId) | ||
793 | struct Host *HostP; | 682 | struct Host *HostP; |
794 | uint UnitId; | 683 | uint 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 | ||
852 | uint | 741 | uint GetUnitType(Uniq) |
853 | GetUnitType(Uniq) | ||
854 | uint Uniq; | 742 | uint 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 | ||
876 | int | 763 | int RIOSetChange(p) |
877 | RIOSetChange(p) | 764 | struct rio_info *p; |
878 | struct 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 | ||
892 | static void | 778 | static void RIOConCon(p, HostP, FromId, FromLink, ToId, ToLink, Change) |
893 | RIOConCon(p, HostP, FromId, FromLink, ToId, ToLink, Change) | 779 | struct rio_info *p; |
894 | struct rio_info * p; | ||
895 | struct Host *HostP; | 780 | struct Host *HostP; |
896 | uint FromId; | 781 | uint FromId; |
897 | uint FromLink; | 782 | uint FromLink; |
898 | uint ToId; | 783 | uint ToId; |
899 | uint ToLink; | 784 | uint ToLink; |
900 | int Change; | 785 | int 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 | */ |
975 | static int | 854 | static int RIORemoveFromSavedTable(struct rio_info *p, struct Map *pMap) |
976 | RIORemoveFromSavedTable(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 | */ |
1002 | static int | 878 | static int RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit) |
1003 | RIOFreeDisconnected(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 *) ¤t_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 | */ |
1069 | int | 939 | int RIOFindFreeID(struct rio_info *p, struct Host *HostP, uint * pID1, uint * pID2) |
1070 | RIOFindFreeID(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 | ||