diff options
Diffstat (limited to 'drivers/char/rio')
-rw-r--r-- | drivers/char/rio/rioboot.c | 1515 |
1 files changed, 704 insertions, 811 deletions
diff --git a/drivers/char/rio/rioboot.c b/drivers/char/rio/rioboot.c index 92df43552f15..9a96fc644e52 100644 --- a/drivers/char/rio/rioboot.c +++ b/drivers/char/rio/rioboot.c | |||
@@ -80,149 +80,141 @@ static char *_rioboot_c_sccs_ = "@(#)rioboot.c 1.3"; | |||
80 | #include "cmdblk.h" | 80 | #include "cmdblk.h" |
81 | #include "route.h" | 81 | #include "route.h" |
82 | 82 | ||
83 | static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct PktCmd *PktCmdP ); | 83 | static int RIOBootComplete(struct rio_info *p, struct Host *HostP, uint Rup, struct PktCmd *PktCmdP); |
84 | 84 | ||
85 | static uchar | 85 | static uchar RIOAtVec2Ctrl[] = { |
86 | RIOAtVec2Ctrl[] = | 86 | /* 0 */ INTERRUPT_DISABLE, |
87 | { | 87 | /* 1 */ INTERRUPT_DISABLE, |
88 | /* 0 */ INTERRUPT_DISABLE, | 88 | /* 2 */ INTERRUPT_DISABLE, |
89 | /* 1 */ INTERRUPT_DISABLE, | 89 | /* 3 */ INTERRUPT_DISABLE, |
90 | /* 2 */ INTERRUPT_DISABLE, | 90 | /* 4 */ INTERRUPT_DISABLE, |
91 | /* 3 */ INTERRUPT_DISABLE, | 91 | /* 5 */ INTERRUPT_DISABLE, |
92 | /* 4 */ INTERRUPT_DISABLE, | 92 | /* 6 */ INTERRUPT_DISABLE, |
93 | /* 5 */ INTERRUPT_DISABLE, | 93 | /* 7 */ INTERRUPT_DISABLE, |
94 | /* 6 */ INTERRUPT_DISABLE, | 94 | /* 8 */ INTERRUPT_DISABLE, |
95 | /* 7 */ INTERRUPT_DISABLE, | 95 | /* 9 */ IRQ_9 | INTERRUPT_ENABLE, |
96 | /* 8 */ INTERRUPT_DISABLE, | ||
97 | /* 9 */ IRQ_9|INTERRUPT_ENABLE, | ||
98 | /* 10 */ INTERRUPT_DISABLE, | 96 | /* 10 */ INTERRUPT_DISABLE, |
99 | /* 11 */ IRQ_11|INTERRUPT_ENABLE, | 97 | /* 11 */ IRQ_11 | INTERRUPT_ENABLE, |
100 | /* 12 */ IRQ_12|INTERRUPT_ENABLE, | 98 | /* 12 */ IRQ_12 | INTERRUPT_ENABLE, |
101 | /* 13 */ INTERRUPT_DISABLE, | 99 | /* 13 */ INTERRUPT_DISABLE, |
102 | /* 14 */ INTERRUPT_DISABLE, | 100 | /* 14 */ INTERRUPT_DISABLE, |
103 | /* 15 */ IRQ_15|INTERRUPT_ENABLE | 101 | /* 15 */ IRQ_15 | INTERRUPT_ENABLE |
104 | }; | 102 | }; |
105 | 103 | ||
106 | /* | 104 | /* |
107 | ** Load in the RTA boot code. | 105 | ** Load in the RTA boot code. |
108 | */ | 106 | */ |
109 | int | 107 | int RIOBootCodeRTA(p, rbp) |
110 | RIOBootCodeRTA(p, rbp) | 108 | struct rio_info *p; |
111 | struct rio_info * p; | 109 | struct DownLoad *rbp; |
112 | struct DownLoad * rbp; | ||
113 | { | 110 | { |
114 | int offset; | 111 | int offset; |
115 | 112 | ||
116 | func_enter (); | 113 | func_enter(); |
117 | 114 | ||
118 | /* Linux doesn't allow you to disable interrupts during a | 115 | /* Linux doesn't allow you to disable interrupts during a |
119 | "copyin". (Crash when a pagefault occurs). */ | 116 | "copyin". (Crash when a pagefault occurs). */ |
120 | /* disable(oldspl); */ | 117 | /* disable(oldspl); */ |
121 | 118 | ||
122 | rio_dprintk (RIO_DEBUG_BOOT, "Data at user address 0x%x\n",(int)rbp->DataP); | 119 | rio_dprintk(RIO_DEBUG_BOOT, "Data at user address 0x%x\n", (int) rbp->DataP); |
123 | 120 | ||
124 | /* | 121 | /* |
125 | ** Check that we have set asside enough memory for this | 122 | ** Check that we have set asside enough memory for this |
126 | */ | 123 | */ |
127 | if ( rbp->Count > SIXTY_FOUR_K ) { | 124 | if (rbp->Count > SIXTY_FOUR_K) { |
128 | rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot Code Too Large!\n"); | 125 | rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot Code Too Large!\n"); |
129 | p->RIOError.Error = HOST_FILE_TOO_LARGE; | 126 | p->RIOError.Error = HOST_FILE_TOO_LARGE; |
130 | /* restore(oldspl); */ | 127 | /* restore(oldspl); */ |
131 | func_exit (); | 128 | func_exit(); |
132 | return -ENOMEM; | 129 | return -ENOMEM; |
133 | } | 130 | } |
134 | 131 | ||
135 | if ( p->RIOBooting ) { | 132 | if (p->RIOBooting) { |
136 | rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot Code : BUSY BUSY BUSY!\n"); | 133 | rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot Code : BUSY BUSY BUSY!\n"); |
137 | p->RIOError.Error = BOOT_IN_PROGRESS; | 134 | p->RIOError.Error = BOOT_IN_PROGRESS; |
138 | /* restore(oldspl); */ | 135 | /* restore(oldspl); */ |
139 | func_exit (); | 136 | func_exit(); |
140 | return -EBUSY; | 137 | return -EBUSY; |
141 | } | 138 | } |
142 | 139 | ||
143 | /* | 140 | /* |
144 | ** The data we load in must end on a (RTA_BOOT_DATA_SIZE) byte boundary, | 141 | ** The data we load in must end on a (RTA_BOOT_DATA_SIZE) byte boundary, |
145 | ** so calculate how far we have to move the data up the buffer | 142 | ** so calculate how far we have to move the data up the buffer |
146 | ** to achieve this. | 143 | ** to achieve this. |
147 | */ | 144 | */ |
148 | offset = (RTA_BOOT_DATA_SIZE - (rbp->Count % RTA_BOOT_DATA_SIZE)) % | 145 | offset = (RTA_BOOT_DATA_SIZE - (rbp->Count % RTA_BOOT_DATA_SIZE)) % RTA_BOOT_DATA_SIZE; |
149 | RTA_BOOT_DATA_SIZE; | ||
150 | 146 | ||
151 | /* | 147 | /* |
152 | ** Be clean, and clear the 'unused' portion of the boot buffer, | 148 | ** Be clean, and clear the 'unused' portion of the boot buffer, |
153 | ** because it will (eventually) be part of the Rta run time environment | 149 | ** because it will (eventually) be part of the Rta run time environment |
154 | ** and so should be zeroed. | 150 | ** and so should be zeroed. |
155 | */ | 151 | */ |
156 | bzero( (caddr_t)p->RIOBootPackets, offset ); | 152 | bzero((caddr_t) p->RIOBootPackets, offset); |
157 | 153 | ||
158 | /* | 154 | /* |
159 | ** Copy the data from user space. | 155 | ** Copy the data from user space. |
160 | */ | 156 | */ |
161 | 157 | ||
162 | if ( copyin((int)rbp->DataP,((caddr_t)(p->RIOBootPackets))+offset, | 158 | if (copyin((int) rbp->DataP, ((caddr_t) (p->RIOBootPackets)) + offset, rbp->Count) == COPYFAIL) { |
163 | rbp->Count) ==COPYFAIL ) { | 159 | rio_dprintk(RIO_DEBUG_BOOT, "Bad data copy from user space\n"); |
164 | rio_dprintk (RIO_DEBUG_BOOT, "Bad data copy from user space\n"); | ||
165 | p->RIOError.Error = COPYIN_FAILED; | 160 | p->RIOError.Error = COPYIN_FAILED; |
166 | /* restore(oldspl); */ | 161 | /* restore(oldspl); */ |
167 | func_exit (); | 162 | func_exit(); |
168 | return -EFAULT; | 163 | return -EFAULT; |
169 | } | 164 | } |
170 | 165 | ||
171 | /* | 166 | /* |
172 | ** Make sure that our copy of the size includes that offset we discussed | 167 | ** Make sure that our copy of the size includes that offset we discussed |
173 | ** earlier. | 168 | ** earlier. |
174 | */ | 169 | */ |
175 | p->RIONumBootPkts = (rbp->Count+offset)/RTA_BOOT_DATA_SIZE; | 170 | p->RIONumBootPkts = (rbp->Count + offset) / RTA_BOOT_DATA_SIZE; |
176 | p->RIOBootCount = rbp->Count; | 171 | p->RIOBootCount = rbp->Count; |
177 | 172 | ||
178 | /* restore(oldspl); */ | 173 | /* restore(oldspl); */ |
179 | func_exit(); | 174 | func_exit(); |
180 | return 0; | 175 | return 0; |
181 | } | 176 | } |
182 | 177 | ||
183 | void rio_start_card_running (struct Host * HostP) | 178 | void rio_start_card_running(struct Host *HostP) |
184 | { | 179 | { |
185 | func_enter (); | 180 | func_enter(); |
186 | 181 | ||
187 | switch ( HostP->Type ) { | 182 | switch (HostP->Type) { |
188 | case RIO_AT: | 183 | case RIO_AT: |
189 | rio_dprintk (RIO_DEBUG_BOOT, "Start ISA card running\n"); | 184 | rio_dprintk(RIO_DEBUG_BOOT, "Start ISA card running\n"); |
190 | WBYTE(HostP->Control, | 185 | WBYTE(HostP->Control, BOOT_FROM_RAM | EXTERNAL_BUS_ON | HostP->Mode | RIOAtVec2Ctrl[HostP->Ivec & 0xF]); |
191 | BOOT_FROM_RAM | EXTERNAL_BUS_ON | ||
192 | | HostP->Mode | ||
193 | | RIOAtVec2Ctrl[HostP->Ivec & 0xF] ); | ||
194 | break; | 186 | break; |
195 | 187 | ||
196 | #ifdef FUTURE_RELEASE | 188 | #ifdef FUTURE_RELEASE |
197 | case RIO_MCA: | 189 | case RIO_MCA: |
198 | /* | 190 | /* |
199 | ** MCA handles IRQ vectors differently, so we don't write | 191 | ** MCA handles IRQ vectors differently, so we don't write |
200 | ** them to this register. | 192 | ** them to this register. |
201 | */ | 193 | */ |
202 | rio_dprintk (RIO_DEBUG_BOOT, "Start MCA card running\n"); | 194 | rio_dprintk(RIO_DEBUG_BOOT, "Start MCA card running\n"); |
203 | WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode); | 195 | WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode); |
204 | break; | 196 | break; |
205 | 197 | ||
206 | case RIO_EISA: | 198 | case RIO_EISA: |
207 | /* | 199 | /* |
208 | ** EISA is totally different and expects OUTBZs to turn it on. | 200 | ** EISA is totally different and expects OUTBZs to turn it on. |
209 | */ | 201 | */ |
210 | rio_dprintk (RIO_DEBUG_BOOT, "Start EISA card running\n"); | 202 | rio_dprintk(RIO_DEBUG_BOOT, "Start EISA card running\n"); |
211 | OUTBZ( HostP->Slot, EISA_CONTROL_PORT, HostP->Mode | RIOEisaVec2Ctrl[HostP->Ivec] | EISA_TP_RUN | EISA_TP_BUS_ENABLE | EISA_TP_BOOT_FROM_RAM ); | 203 | OUTBZ(HostP->Slot, EISA_CONTROL_PORT, HostP->Mode | RIOEisaVec2Ctrl[HostP->Ivec] | EISA_TP_RUN | EISA_TP_BUS_ENABLE | EISA_TP_BOOT_FROM_RAM); |
212 | break; | 204 | break; |
213 | #endif | 205 | #endif |
214 | 206 | ||
215 | case RIO_PCI: | 207 | case RIO_PCI: |
216 | /* | 208 | /* |
217 | ** PCI is much the same as MCA. Everything is once again memory | 209 | ** PCI is much the same as MCA. Everything is once again memory |
218 | ** mapped, so we are writing to memory registers instead of io | 210 | ** mapped, so we are writing to memory registers instead of io |
219 | ** ports. | 211 | ** ports. |
220 | */ | 212 | */ |
221 | rio_dprintk (RIO_DEBUG_BOOT, "Start PCI card running\n"); | 213 | rio_dprintk(RIO_DEBUG_BOOT, "Start PCI card running\n"); |
222 | WBYTE(HostP->Control, PCITpBootFromRam | PCITpBusEnable | HostP->Mode); | 214 | WBYTE(HostP->Control, PCITpBootFromRam | PCITpBusEnable | HostP->Mode); |
223 | break; | 215 | break; |
224 | default: | 216 | default: |
225 | rio_dprintk (RIO_DEBUG_BOOT, "Unknown host type %d\n", HostP->Type); | 217 | rio_dprintk(RIO_DEBUG_BOOT, "Unknown host type %d\n", HostP->Type); |
226 | break; | 218 | break; |
227 | } | 219 | } |
228 | /* | 220 | /* |
@@ -239,9 +231,8 @@ void rio_start_card_running (struct Host * HostP) | |||
239 | ** Put your rubber pants on before messing with this code - even the magic | 231 | ** Put your rubber pants on before messing with this code - even the magic |
240 | ** numbers have trouble understanding what they are doing here. | 232 | ** numbers have trouble understanding what they are doing here. |
241 | */ | 233 | */ |
242 | int | 234 | int RIOBootCodeHOST(p, rbp) |
243 | RIOBootCodeHOST(p, rbp) | 235 | struct rio_info *p; |
244 | struct rio_info * p; | ||
245 | register struct DownLoad *rbp; | 236 | register struct DownLoad *rbp; |
246 | { | 237 | { |
247 | register struct Host *HostP; | 238 | register struct Host *HostP; |
@@ -254,355 +245,346 @@ register struct DownLoad *rbp; | |||
254 | BYTE *DestP; | 245 | BYTE *DestP; |
255 | int wait_count; | 246 | int wait_count; |
256 | ushort OldParmMap; | 247 | ushort OldParmMap; |
257 | ushort offset; /* It is very important that this is a ushort */ | 248 | ushort offset; /* It is very important that this is a ushort */ |
258 | /* uint byte; */ | 249 | /* uint byte; */ |
259 | caddr_t DownCode = NULL; | 250 | caddr_t DownCode = NULL; |
260 | unsigned long flags; | 251 | unsigned long flags; |
261 | 252 | ||
262 | HostP = NULL; /* Assure the compiler we've initialized it */ | 253 | HostP = NULL; /* Assure the compiler we've initialized it */ |
263 | for ( host=0; host<p->RIONumHosts; host++ ) { | 254 | for (host = 0; host < p->RIONumHosts; host++) { |
264 | rio_dprintk (RIO_DEBUG_BOOT, "Attempt to boot host %d\n",host); | 255 | rio_dprintk(RIO_DEBUG_BOOT, "Attempt to boot host %d\n", host); |
265 | HostP = &p->RIOHosts[host]; | 256 | HostP = &p->RIOHosts[host]; |
266 | |||
267 | rio_dprintk (RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", | ||
268 | HostP->Type, HostP->Mode, HostP->Ivec); | ||
269 | 257 | ||
258 | rio_dprintk(RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", HostP->Type, HostP->Mode, HostP->Ivec); | ||
270 | 259 | ||
271 | if ( (HostP->Flags & RUN_STATE) != RC_WAITING ) { | 260 | |
272 | rio_dprintk (RIO_DEBUG_BOOT, "%s %d already running\n","Host",host); | 261 | if ((HostP->Flags & RUN_STATE) != RC_WAITING) { |
262 | rio_dprintk(RIO_DEBUG_BOOT, "%s %d already running\n", "Host", host); | ||
273 | continue; | 263 | continue; |
274 | } | 264 | } |
275 | 265 | ||
276 | /* | 266 | /* |
277 | ** Grab a 32 bit pointer to the card. | 267 | ** Grab a 32 bit pointer to the card. |
278 | */ | 268 | */ |
279 | Cad = HostP->Caddr; | 269 | Cad = HostP->Caddr; |
280 | 270 | ||
281 | /* | 271 | /* |
282 | ** We are going to (try) and load in rbp->Count bytes. | 272 | ** We are going to (try) and load in rbp->Count bytes. |
283 | ** The last byte will reside at p->RIOConf.HostLoadBase-1; | 273 | ** The last byte will reside at p->RIOConf.HostLoadBase-1; |
284 | ** Therefore, we need to start copying at address | 274 | ** Therefore, we need to start copying at address |
285 | ** (caddr+p->RIOConf.HostLoadBase-rbp->Count) | 275 | ** (caddr+p->RIOConf.HostLoadBase-rbp->Count) |
286 | */ | 276 | */ |
287 | StartP = (caddr_t)&Cad[p->RIOConf.HostLoadBase-rbp->Count]; | 277 | StartP = (caddr_t) & Cad[p->RIOConf.HostLoadBase - rbp->Count]; |
288 | 278 | ||
289 | rio_dprintk (RIO_DEBUG_BOOT, "kernel virtual address for host is 0x%x\n", (int)Cad ); | 279 | rio_dprintk(RIO_DEBUG_BOOT, "kernel virtual address for host is 0x%x\n", (int) Cad); |
290 | rio_dprintk (RIO_DEBUG_BOOT, "kernel virtual address for download is 0x%x\n", (int)StartP); | 280 | rio_dprintk(RIO_DEBUG_BOOT, "kernel virtual address for download is 0x%x\n", (int) StartP); |
291 | rio_dprintk (RIO_DEBUG_BOOT, "host loadbase is 0x%x\n",p->RIOConf.HostLoadBase); | 281 | rio_dprintk(RIO_DEBUG_BOOT, "host loadbase is 0x%x\n", p->RIOConf.HostLoadBase); |
292 | rio_dprintk (RIO_DEBUG_BOOT, "size of download is 0x%x\n", rbp->Count); | 282 | rio_dprintk(RIO_DEBUG_BOOT, "size of download is 0x%x\n", rbp->Count); |
293 | 283 | ||
294 | if ( p->RIOConf.HostLoadBase < rbp->Count ) { | 284 | if (p->RIOConf.HostLoadBase < rbp->Count) { |
295 | rio_dprintk (RIO_DEBUG_BOOT, "Bin too large\n"); | 285 | rio_dprintk(RIO_DEBUG_BOOT, "Bin too large\n"); |
296 | p->RIOError.Error = HOST_FILE_TOO_LARGE; | 286 | p->RIOError.Error = HOST_FILE_TOO_LARGE; |
297 | func_exit (); | 287 | func_exit(); |
298 | return -EFBIG; | 288 | return -EFBIG; |
299 | } | 289 | } |
300 | /* | 290 | /* |
301 | ** Ensure that the host really is stopped. | 291 | ** Ensure that the host really is stopped. |
302 | ** Disable it's external bus & twang its reset line. | 292 | ** Disable it's external bus & twang its reset line. |
303 | */ | 293 | */ |
304 | RIOHostReset( HostP->Type, (struct DpRam *)HostP->CardP, HostP->Slot ); | 294 | RIOHostReset(HostP->Type, (struct DpRam *) HostP->CardP, HostP->Slot); |
305 | 295 | ||
306 | /* | 296 | /* |
307 | ** Copy the data directly from user space to the SRAM. | 297 | ** Copy the data directly from user space to the SRAM. |
308 | ** This ain't going to be none too clever if the download | 298 | ** This ain't going to be none too clever if the download |
309 | ** code is bigger than this segment. | 299 | ** code is bigger than this segment. |
310 | */ | 300 | */ |
311 | rio_dprintk (RIO_DEBUG_BOOT, "Copy in code\n"); | 301 | rio_dprintk(RIO_DEBUG_BOOT, "Copy in code\n"); |
312 | 302 | ||
313 | /* | 303 | /* |
314 | ** PCI hostcard can't cope with 32 bit accesses and so need to copy | 304 | ** PCI hostcard can't cope with 32 bit accesses and so need to copy |
315 | ** data to a local buffer, and then dripfeed the card. | 305 | ** data to a local buffer, and then dripfeed the card. |
316 | */ | 306 | */ |
317 | if ( HostP->Type == RIO_PCI ) { | 307 | if (HostP->Type == RIO_PCI) { |
318 | /* int offset; */ | 308 | /* int offset; */ |
319 | 309 | ||
320 | DownCode = sysbrk(rbp->Count); | 310 | DownCode = sysbrk(rbp->Count); |
321 | if ( !DownCode ) { | 311 | if (!DownCode) { |
322 | rio_dprintk (RIO_DEBUG_BOOT, "No system memory available\n"); | 312 | rio_dprintk(RIO_DEBUG_BOOT, "No system memory available\n"); |
323 | p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY; | 313 | p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY; |
324 | func_exit (); | 314 | func_exit(); |
325 | return -ENOMEM; | 315 | return -ENOMEM; |
326 | } | 316 | } |
327 | bzero(DownCode, rbp->Count); | 317 | bzero(DownCode, rbp->Count); |
328 | 318 | ||
329 | if ( copyin((int)rbp->DataP,DownCode,rbp->Count)==COPYFAIL ) { | 319 | if (copyin((int) rbp->DataP, DownCode, rbp->Count) == COPYFAIL) { |
330 | rio_dprintk (RIO_DEBUG_BOOT, "Bad copyin of host data\n"); | 320 | rio_dprintk(RIO_DEBUG_BOOT, "Bad copyin of host data\n"); |
331 | sysfree( DownCode, rbp->Count ); | 321 | sysfree(DownCode, rbp->Count); |
332 | p->RIOError.Error = COPYIN_FAILED; | 322 | p->RIOError.Error = COPYIN_FAILED; |
333 | func_exit (); | 323 | func_exit(); |
334 | return -EFAULT; | 324 | return -EFAULT; |
335 | } | 325 | } |
336 | 326 | ||
337 | HostP->Copy( DownCode, StartP, rbp->Count ); | 327 | HostP->Copy(DownCode, StartP, rbp->Count); |
338 | 328 | ||
339 | sysfree( DownCode, rbp->Count ); | 329 | sysfree(DownCode, rbp->Count); |
340 | } | 330 | } else if (copyin((int) rbp->DataP, StartP, rbp->Count) == COPYFAIL) { |
341 | else if ( copyin((int)rbp->DataP,StartP,rbp->Count)==COPYFAIL ) { | 331 | rio_dprintk(RIO_DEBUG_BOOT, "Bad copyin of host data\n"); |
342 | rio_dprintk (RIO_DEBUG_BOOT, "Bad copyin of host data\n"); | ||
343 | p->RIOError.Error = COPYIN_FAILED; | 332 | p->RIOError.Error = COPYIN_FAILED; |
344 | func_exit (); | 333 | func_exit(); |
345 | return -EFAULT; | 334 | return -EFAULT; |
346 | } | 335 | } |
347 | 336 | ||
348 | rio_dprintk (RIO_DEBUG_BOOT, "Copy completed\n"); | 337 | rio_dprintk(RIO_DEBUG_BOOT, "Copy completed\n"); |
349 | 338 | ||
350 | /* | 339 | /* |
351 | ** S T O P ! | 340 | ** S T O P ! |
352 | ** | 341 | ** |
353 | ** Upto this point the code has been fairly rational, and possibly | 342 | ** Upto this point the code has been fairly rational, and possibly |
354 | ** even straight forward. What follows is a pile of crud that will | 343 | ** even straight forward. What follows is a pile of crud that will |
355 | ** magically turn into six bytes of transputer assembler. Normally | 344 | ** magically turn into six bytes of transputer assembler. Normally |
356 | ** you would expect an array or something, but, being me, I have | 345 | ** you would expect an array or something, but, being me, I have |
357 | ** chosen [been told] to use a technique whereby the startup code | 346 | ** chosen [been told] to use a technique whereby the startup code |
358 | ** will be correct if we change the loadbase for the code. Which | 347 | ** will be correct if we change the loadbase for the code. Which |
359 | ** brings us onto another issue - the loadbase is the *end* of the | 348 | ** brings us onto another issue - the loadbase is the *end* of the |
360 | ** code, not the start. | 349 | ** code, not the start. |
361 | ** | 350 | ** |
362 | ** If I were you I wouldn't start from here. | 351 | ** If I were you I wouldn't start from here. |
363 | */ | 352 | */ |
364 | 353 | ||
365 | /* | 354 | /* |
366 | ** We now need to insert a short boot section into | 355 | ** We now need to insert a short boot section into |
367 | ** the memory at the end of Sram2. This is normally (de)composed | 356 | ** the memory at the end of Sram2. This is normally (de)composed |
368 | ** of the last eight bytes of the download code. The | 357 | ** of the last eight bytes of the download code. The |
369 | ** download has been assembled/compiled to expect to be | 358 | ** download has been assembled/compiled to expect to be |
370 | ** loaded from 0x7FFF downwards. We have loaded it | 359 | ** loaded from 0x7FFF downwards. We have loaded it |
371 | ** at some other address. The startup code goes into the small | 360 | ** at some other address. The startup code goes into the small |
372 | ** ram window at Sram2, in the last 8 bytes, which are really | 361 | ** ram window at Sram2, in the last 8 bytes, which are really |
373 | ** at addresses 0x7FF8-0x7FFF. | 362 | ** at addresses 0x7FF8-0x7FFF. |
374 | ** | 363 | ** |
375 | ** If the loadbase is, say, 0x7C00, then we need to branch to | 364 | ** If the loadbase is, say, 0x7C00, then we need to branch to |
376 | ** address 0x7BFE to run the host.bin startup code. We assemble | 365 | ** address 0x7BFE to run the host.bin startup code. We assemble |
377 | ** this jump manually. | 366 | ** this jump manually. |
378 | ** | 367 | ** |
379 | ** The two byte sequence 60 08 is loaded into memory at address | 368 | ** The two byte sequence 60 08 is loaded into memory at address |
380 | ** 0x7FFE,F. This is a local branch to location 0x7FF8 (60 is nfix 0, | 369 | ** 0x7FFE,F. This is a local branch to location 0x7FF8 (60 is nfix 0, |
381 | ** which adds '0' to the .O register, complements .O, and then shifts | 370 | ** which adds '0' to the .O register, complements .O, and then shifts |
382 | ** it left by 4 bit positions, 08 is a jump .O+8 instruction. This will | 371 | ** it left by 4 bit positions, 08 is a jump .O+8 instruction. This will |
383 | ** add 8 to .O (which was 0xFFF0), and will branch RELATIVE to the new | 372 | ** add 8 to .O (which was 0xFFF0), and will branch RELATIVE to the new |
384 | ** location. Now, the branch starts from the value of .PC (or .IP or | 373 | ** location. Now, the branch starts from the value of .PC (or .IP or |
385 | ** whatever the bloody register is called on this chip), and the .PC | 374 | ** whatever the bloody register is called on this chip), and the .PC |
386 | ** will be pointing to the location AFTER the branch, in this case | 375 | ** will be pointing to the location AFTER the branch, in this case |
387 | ** .PC == 0x8000, so the branch will be to 0x8000+0xFFF8 = 0x7FF8. | 376 | ** .PC == 0x8000, so the branch will be to 0x8000+0xFFF8 = 0x7FF8. |
388 | ** | 377 | ** |
389 | ** A long branch is coded at 0x7FF8. This consists of loading a four | 378 | ** A long branch is coded at 0x7FF8. This consists of loading a four |
390 | ** byte offset into .O using nfix (as above) and pfix operators. The | 379 | ** byte offset into .O using nfix (as above) and pfix operators. The |
391 | ** pfix operates in exactly the same way as the nfix operator, but | 380 | ** pfix operates in exactly the same way as the nfix operator, but |
392 | ** without the complement operation. The offset, of course, must be | 381 | ** without the complement operation. The offset, of course, must be |
393 | ** relative to the address of the byte AFTER the branch instruction, | 382 | ** relative to the address of the byte AFTER the branch instruction, |
394 | ** which will be (urm) 0x7FFC, so, our final destination of the branch | 383 | ** which will be (urm) 0x7FFC, so, our final destination of the branch |
395 | ** (loadbase-2), has to be reached from here. Imagine that the loadbase | 384 | ** (loadbase-2), has to be reached from here. Imagine that the loadbase |
396 | ** is 0x7C00 (which it is), then we will need to branch to 0x7BFE (which | 385 | ** is 0x7C00 (which it is), then we will need to branch to 0x7BFE (which |
397 | ** is the first byte of the initial two byte short local branch of the | 386 | ** is the first byte of the initial two byte short local branch of the |
398 | ** download code). | 387 | ** download code). |
399 | ** | 388 | ** |
400 | ** To code a jump from 0x7FFC (which is where the branch will start | 389 | ** To code a jump from 0x7FFC (which is where the branch will start |
401 | ** from) to 0x7BFE, we will need to branch 0xFC02 bytes (0x7FFC+0xFC02)= | 390 | ** from) to 0x7BFE, we will need to branch 0xFC02 bytes (0x7FFC+0xFC02)= |
402 | ** 0x7BFE. | 391 | ** 0x7BFE. |
403 | ** This will be coded as four bytes: | 392 | ** This will be coded as four bytes: |
404 | ** 60 2C 20 02 | 393 | ** 60 2C 20 02 |
405 | ** being nfix .O+0 | 394 | ** being nfix .O+0 |
406 | ** pfix .O+C | 395 | ** pfix .O+C |
407 | ** pfix .O+0 | 396 | ** pfix .O+0 |
408 | ** jump .O+2 | 397 | ** jump .O+2 |
409 | ** | 398 | ** |
410 | ** The nfix operator is used, so that the startup code will be | 399 | ** The nfix operator is used, so that the startup code will be |
411 | ** compatible with the whole Tp family. (lies, damn lies, it'll never | 400 | ** compatible with the whole Tp family. (lies, damn lies, it'll never |
412 | ** work in a month of Sundays). | 401 | ** work in a month of Sundays). |
413 | ** | 402 | ** |
414 | ** The nfix nyble is the 1s complement of the nyble value you | 403 | ** The nfix nyble is the 1s complement of the nyble value you |
415 | ** want to load - in this case we wanted 'F' so we nfix loaded '0'. | 404 | ** want to load - in this case we wanted 'F' so we nfix loaded '0'. |
416 | */ | 405 | */ |
417 | 406 | ||
418 | 407 | ||
419 | /* | 408 | /* |
420 | ** Dest points to the top 8 bytes of Sram2. The Tp jumps | 409 | ** Dest points to the top 8 bytes of Sram2. The Tp jumps |
421 | ** to 0x7FFE at reset time, and starts executing. This is | 410 | ** to 0x7FFE at reset time, and starts executing. This is |
422 | ** a short branch to 0x7FF8, where a long branch is coded. | 411 | ** a short branch to 0x7FF8, where a long branch is coded. |
423 | */ | 412 | */ |
424 | 413 | ||
425 | DestP = (BYTE *)&Cad[0x7FF8]; /* <<<---- READ THE ABOVE COMMENTS */ | 414 | DestP = (BYTE *) & Cad[0x7FF8]; /* <<<---- READ THE ABOVE COMMENTS */ |
426 | 415 | ||
427 | #define NFIX(N) (0x60 | (N)) /* .O = (~(.O + N))<<4 */ | 416 | #define NFIX(N) (0x60 | (N)) /* .O = (~(.O + N))<<4 */ |
428 | #define PFIX(N) (0x20 | (N)) /* .O = (.O + N)<<4 */ | 417 | #define PFIX(N) (0x20 | (N)) /* .O = (.O + N)<<4 */ |
429 | #define JUMP(N) (0x00 | (N)) /* .PC = .PC + .O */ | 418 | #define JUMP(N) (0x00 | (N)) /* .PC = .PC + .O */ |
430 | 419 | ||
431 | /* | 420 | /* |
432 | ** 0x7FFC is the address of the location following the last byte of | 421 | ** 0x7FFC is the address of the location following the last byte of |
433 | ** the four byte jump instruction. | 422 | ** the four byte jump instruction. |
434 | ** READ THE ABOVE COMMENTS | 423 | ** READ THE ABOVE COMMENTS |
435 | ** | 424 | ** |
436 | ** offset is (TO-FROM) % MEMSIZE, but with compound buggering about. | 425 | ** offset is (TO-FROM) % MEMSIZE, but with compound buggering about. |
437 | ** Memsize is 64K for this range of Tp, so offset is a short (unsigned, | 426 | ** Memsize is 64K for this range of Tp, so offset is a short (unsigned, |
438 | ** cos I don't understand 2's complement). | 427 | ** cos I don't understand 2's complement). |
439 | */ | 428 | */ |
440 | offset = (p->RIOConf.HostLoadBase-2)-0x7FFC; | 429 | offset = (p->RIOConf.HostLoadBase - 2) - 0x7FFC; |
441 | WBYTE( DestP[0] , NFIX(((ushort)(~offset) >> (ushort)12) & 0xF) ); | 430 | WBYTE(DestP[0], NFIX(((ushort) (~offset) >> (ushort) 12) & 0xF)); |
442 | WBYTE( DestP[1] , PFIX(( offset >> 8) & 0xF) ); | 431 | WBYTE(DestP[1], PFIX((offset >> 8) & 0xF)); |
443 | WBYTE( DestP[2] , PFIX(( offset >> 4) & 0xF) ); | 432 | WBYTE(DestP[2], PFIX((offset >> 4) & 0xF)); |
444 | WBYTE( DestP[3] , JUMP( offset & 0xF) ); | 433 | WBYTE(DestP[3], JUMP(offset & 0xF)); |
445 | 434 | ||
446 | WBYTE( DestP[6] , NFIX(0) ); | 435 | WBYTE(DestP[6], NFIX(0)); |
447 | WBYTE( DestP[7] , JUMP(8) ); | 436 | WBYTE(DestP[7], JUMP(8)); |
448 | 437 | ||
449 | rio_dprintk (RIO_DEBUG_BOOT, "host loadbase is 0x%x\n",p->RIOConf.HostLoadBase); | 438 | rio_dprintk(RIO_DEBUG_BOOT, "host loadbase is 0x%x\n", p->RIOConf.HostLoadBase); |
450 | rio_dprintk (RIO_DEBUG_BOOT, "startup offset is 0x%x\n",offset); | 439 | rio_dprintk(RIO_DEBUG_BOOT, "startup offset is 0x%x\n", offset); |
451 | 440 | ||
452 | /* | 441 | /* |
453 | ** Flag what is going on | 442 | ** Flag what is going on |
454 | */ | 443 | */ |
455 | HostP->Flags &= ~RUN_STATE; | 444 | HostP->Flags &= ~RUN_STATE; |
456 | HostP->Flags |= RC_STARTUP; | 445 | HostP->Flags |= RC_STARTUP; |
457 | 446 | ||
458 | /* | 447 | /* |
459 | ** Grab a copy of the current ParmMap pointer, so we | 448 | ** Grab a copy of the current ParmMap pointer, so we |
460 | ** can tell when it has changed. | 449 | ** can tell when it has changed. |
461 | */ | 450 | */ |
462 | OldParmMap = RWORD(HostP->__ParmMapR); | 451 | OldParmMap = RWORD(HostP->__ParmMapR); |
463 | 452 | ||
464 | rio_dprintk (RIO_DEBUG_BOOT, "Original parmmap is 0x%x\n",OldParmMap); | 453 | rio_dprintk(RIO_DEBUG_BOOT, "Original parmmap is 0x%x\n", OldParmMap); |
465 | 454 | ||
466 | /* | 455 | /* |
467 | ** And start it running (I hope). | 456 | ** And start it running (I hope). |
468 | ** As there is nothing dodgy or obscure about the | 457 | ** As there is nothing dodgy or obscure about the |
469 | ** above code, this is guaranteed to work every time. | 458 | ** above code, this is guaranteed to work every time. |
470 | */ | 459 | */ |
471 | rio_dprintk (RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", | 460 | rio_dprintk(RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", HostP->Type, HostP->Mode, HostP->Ivec); |
472 | HostP->Type, HostP->Mode, HostP->Ivec); | ||
473 | 461 | ||
474 | rio_start_card_running(HostP); | 462 | rio_start_card_running(HostP); |
475 | 463 | ||
476 | rio_dprintk (RIO_DEBUG_BOOT, "Set control port\n"); | 464 | rio_dprintk(RIO_DEBUG_BOOT, "Set control port\n"); |
477 | 465 | ||
478 | /* | 466 | /* |
479 | ** Now, wait for upto five seconds for the Tp to setup the parmmap | 467 | ** Now, wait for upto five seconds for the Tp to setup the parmmap |
480 | ** pointer: | 468 | ** pointer: |
481 | */ | 469 | */ |
482 | for ( wait_count=0; (wait_count<p->RIOConf.StartupTime)&& | 470 | for (wait_count = 0; (wait_count < p->RIOConf.StartupTime) && (RWORD(HostP->__ParmMapR) == OldParmMap); wait_count++) { |
483 | (RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) { | 471 | rio_dprintk(RIO_DEBUG_BOOT, "Checkout %d, 0x%x\n", wait_count, RWORD(HostP->__ParmMapR)); |
484 | rio_dprintk (RIO_DEBUG_BOOT, "Checkout %d, 0x%x\n",wait_count,RWORD(HostP->__ParmMapR)); | ||
485 | delay(HostP, HUNDRED_MS); | 472 | delay(HostP, HUNDRED_MS); |
486 | 473 | ||
487 | } | 474 | } |
488 | 475 | ||
489 | /* | 476 | /* |
490 | ** If the parmmap pointer is unchanged, then the host code | 477 | ** If the parmmap pointer is unchanged, then the host code |
491 | ** has crashed & burned in a really spectacular way | 478 | ** has crashed & burned in a really spectacular way |
492 | */ | 479 | */ |
493 | if ( RWORD(HostP->__ParmMapR) == OldParmMap ) { | 480 | if (RWORD(HostP->__ParmMapR) == OldParmMap) { |
494 | rio_dprintk (RIO_DEBUG_BOOT, "parmmap 0x%x\n", RWORD(HostP->__ParmMapR)); | 481 | rio_dprintk(RIO_DEBUG_BOOT, "parmmap 0x%x\n", RWORD(HostP->__ParmMapR)); |
495 | rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n"); | 482 | rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n"); |
496 | 483 | HostP->Flags &= ~RUN_STATE; | |
497 | #define HOST_DISABLE \ | 484 | HostP->Flags |= RC_STUFFED; |
498 | HostP->Flags &= ~RUN_STATE; \ | 485 | RIOHostReset(HostP->Type, (struct DpRam *) HostP->CardP, HostP->Slot); |
499 | HostP->Flags |= RC_STUFFED; \ | 486 | continue} |
500 | RIOHostReset( HostP->Type, (struct DpRam *)HostP->CardP, HostP->Slot );\ | 487 | |
501 | continue | 488 | rio_dprintk(RIO_DEBUG_BOOT, "Running 0x%x\n", RWORD(HostP->__ParmMapR)); |
502 | |||
503 | HOST_DISABLE; | ||
504 | } | ||
505 | |||
506 | rio_dprintk (RIO_DEBUG_BOOT, "Running 0x%x\n", RWORD(HostP->__ParmMapR)); | ||
507 | 489 | ||
508 | /* | 490 | /* |
509 | ** Well, the board thought it was OK, and setup its parmmap | 491 | ** Well, the board thought it was OK, and setup its parmmap |
510 | ** pointer. For the time being, we will pretend that this | 492 | ** pointer. For the time being, we will pretend that this |
511 | ** board is running, and check out what the error flag says. | 493 | ** board is running, and check out what the error flag says. |
512 | */ | 494 | */ |
513 | 495 | ||
514 | /* | 496 | /* |
515 | ** Grab a 32 bit pointer to the parmmap structure | 497 | ** Grab a 32 bit pointer to the parmmap structure |
516 | */ | 498 | */ |
517 | ParmMapP = (PARM_MAP *)RIO_PTR(Cad,RWORD(HostP->__ParmMapR)); | 499 | ParmMapP = (PARM_MAP *) RIO_PTR(Cad, RWORD(HostP->__ParmMapR)); |
518 | rio_dprintk (RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int)ParmMapP); | 500 | rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int) ParmMapP); |
519 | ParmMapP = (PARM_MAP *)((unsigned long)Cad + | 501 | ParmMapP = (PARM_MAP *) ((unsigned long) Cad + (unsigned long) ((RWORD((HostP->__ParmMapR))) & 0xFFFF)); |
520 | (unsigned long)((RWORD((HostP->__ParmMapR))) & 0xFFFF)); | 502 | rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int) ParmMapP); |
521 | rio_dprintk (RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int)ParmMapP); | ||
522 | 503 | ||
523 | /* | 504 | /* |
524 | ** The links entry should be 0xFFFF; we set it up | 505 | ** The links entry should be 0xFFFF; we set it up |
525 | ** with a mask to say how many PHBs to use, and | 506 | ** with a mask to say how many PHBs to use, and |
526 | ** which links to use. | 507 | ** which links to use. |
527 | */ | 508 | */ |
528 | if ( (RWORD(ParmMapP->links) & 0xFFFF) != 0xFFFF ) { | 509 | if ((RWORD(ParmMapP->links) & 0xFFFF) != 0xFFFF) { |
529 | rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name); | 510 | rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name); |
530 | rio_dprintk (RIO_DEBUG_BOOT, "Links = 0x%x\n",RWORD(ParmMapP->links)); | 511 | rio_dprintk(RIO_DEBUG_BOOT, "Links = 0x%x\n", RWORD(ParmMapP->links)); |
531 | HOST_DISABLE; | 512 | HostP->Flags &= ~RUN_STATE; |
532 | } | 513 | HostP->Flags |= RC_STUFFED; |
533 | 514 | RIOHostReset(HostP->Type, (struct DpRam *) HostP->CardP, HostP->Slot); | |
534 | WWORD(ParmMapP->links , RIO_LINK_ENABLE); | 515 | continue} |
516 | |||
517 | WWORD(ParmMapP->links, RIO_LINK_ENABLE); | ||
535 | 518 | ||
536 | /* | 519 | /* |
537 | ** now wait for the card to set all the parmmap->XXX stuff | 520 | ** now wait for the card to set all the parmmap->XXX stuff |
538 | ** this is a wait of upto two seconds.... | 521 | ** this is a wait of upto two seconds.... |
539 | */ | 522 | */ |
540 | rio_dprintk (RIO_DEBUG_BOOT, "Looking for init_done - %d ticks\n",p->RIOConf.StartupTime); | 523 | rio_dprintk(RIO_DEBUG_BOOT, "Looking for init_done - %d ticks\n", p->RIOConf.StartupTime); |
541 | HostP->timeout_id = 0; | 524 | HostP->timeout_id = 0; |
542 | for ( wait_count=0; (wait_count<p->RIOConf.StartupTime) && | 525 | for (wait_count = 0; (wait_count < p->RIOConf.StartupTime) && !RWORD(ParmMapP->init_done); wait_count++) { |
543 | !RWORD(ParmMapP->init_done); wait_count++ ) { | 526 | rio_dprintk(RIO_DEBUG_BOOT, "Waiting for init_done\n"); |
544 | rio_dprintk (RIO_DEBUG_BOOT, "Waiting for init_done\n"); | ||
545 | delay(HostP, HUNDRED_MS); | 527 | delay(HostP, HUNDRED_MS); |
546 | } | 528 | } |
547 | rio_dprintk (RIO_DEBUG_BOOT, "OK! init_done!\n"); | 529 | rio_dprintk(RIO_DEBUG_BOOT, "OK! init_done!\n"); |
548 | 530 | ||
549 | if (RWORD(ParmMapP->error) != E_NO_ERROR || | 531 | if (RWORD(ParmMapP->error) != E_NO_ERROR || !RWORD(ParmMapP->init_done)) { |
550 | !RWORD(ParmMapP->init_done) ) { | 532 | rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name); |
551 | rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name); | 533 | rio_dprintk(RIO_DEBUG_BOOT, "Timedout waiting for init_done\n"); |
552 | rio_dprintk (RIO_DEBUG_BOOT, "Timedout waiting for init_done\n"); | 534 | HostP->Flags &= ~RUN_STATE; |
553 | HOST_DISABLE; | 535 | HostP->Flags |= RC_STUFFED; |
554 | } | 536 | RIOHostReset(HostP->Type, (struct DpRam *) HostP->CardP, HostP->Slot); |
537 | continue} | ||
555 | 538 | ||
556 | rio_dprintk (RIO_DEBUG_BOOT, "Got init_done\n"); | 539 | rio_dprintk(RIO_DEBUG_BOOT, "Got init_done\n"); |
557 | 540 | ||
558 | /* | 541 | /* |
559 | ** It runs! It runs! | 542 | ** It runs! It runs! |
560 | */ | 543 | */ |
561 | rio_dprintk (RIO_DEBUG_BOOT, "Host ID %x Running\n",HostP->UniqueNum); | 544 | rio_dprintk(RIO_DEBUG_BOOT, "Host ID %x Running\n", HostP->UniqueNum); |
562 | 545 | ||
563 | /* | 546 | /* |
564 | ** set the time period between interrupts. | 547 | ** set the time period between interrupts. |
565 | */ | 548 | */ |
566 | WWORD(ParmMapP->timer, (short)p->RIOConf.Timer ); | 549 | WWORD(ParmMapP->timer, (short) p->RIOConf.Timer); |
567 | 550 | ||
568 | /* | 551 | /* |
569 | ** Translate all the 16 bit pointers in the __ParmMapR into | 552 | ** Translate all the 16 bit pointers in the __ParmMapR into |
570 | ** 32 bit pointers for the driver. | 553 | ** 32 bit pointers for the driver. |
571 | */ | 554 | */ |
572 | HostP->ParmMapP = ParmMapP; | 555 | HostP->ParmMapP = ParmMapP; |
573 | HostP->PhbP = (PHB*)RIO_PTR(Cad,RWORD(ParmMapP->phb_ptr)); | 556 | HostP->PhbP = (PHB *) RIO_PTR(Cad, RWORD(ParmMapP->phb_ptr)); |
574 | HostP->RupP = (RUP*)RIO_PTR(Cad,RWORD(ParmMapP->rups)); | 557 | HostP->RupP = (RUP *) RIO_PTR(Cad, RWORD(ParmMapP->rups)); |
575 | HostP->PhbNumP = (ushort*)RIO_PTR(Cad,RWORD(ParmMapP->phb_num_ptr)); | 558 | HostP->PhbNumP = (ushort *) RIO_PTR(Cad, RWORD(ParmMapP->phb_num_ptr)); |
576 | HostP->LinkStrP = (LPB*)RIO_PTR(Cad,RWORD(ParmMapP->link_str_ptr)); | 559 | HostP->LinkStrP = (LPB *) RIO_PTR(Cad, RWORD(ParmMapP->link_str_ptr)); |
577 | 560 | ||
578 | /* | 561 | /* |
579 | ** point the UnixRups at the real Rups | 562 | ** point the UnixRups at the real Rups |
580 | */ | 563 | */ |
581 | for ( RupN = 0; RupN<MAX_RUP; RupN++ ) { | 564 | for (RupN = 0; RupN < MAX_RUP; RupN++) { |
582 | HostP->UnixRups[RupN].RupP = &HostP->RupP[RupN]; | 565 | HostP->UnixRups[RupN].RupP = &HostP->RupP[RupN]; |
583 | HostP->UnixRups[RupN].Id = RupN+1; | 566 | HostP->UnixRups[RupN].Id = RupN + 1; |
584 | HostP->UnixRups[RupN].BaseSysPort = NO_PORT; | 567 | HostP->UnixRups[RupN].BaseSysPort = NO_PORT; |
585 | spin_lock_init(&HostP->UnixRups[RupN].RupLock); | 568 | spin_lock_init(&HostP->UnixRups[RupN].RupLock); |
586 | } | 569 | } |
587 | 570 | ||
588 | for ( RupN = 0; RupN<LINKS_PER_UNIT; RupN++ ) { | 571 | for (RupN = 0; RupN < LINKS_PER_UNIT; RupN++) { |
589 | HostP->UnixRups[RupN+MAX_RUP].RupP = &HostP->LinkStrP[RupN].rup; | 572 | HostP->UnixRups[RupN + MAX_RUP].RupP = &HostP->LinkStrP[RupN].rup; |
590 | HostP->UnixRups[RupN+MAX_RUP].Id = 0; | 573 | HostP->UnixRups[RupN + MAX_RUP].Id = 0; |
591 | HostP->UnixRups[RupN+MAX_RUP].BaseSysPort = NO_PORT; | 574 | HostP->UnixRups[RupN + MAX_RUP].BaseSysPort = NO_PORT; |
592 | spin_lock_init(&HostP->UnixRups[RupN+MAX_RUP].RupLock); | 575 | spin_lock_init(&HostP->UnixRups[RupN + MAX_RUP].RupLock); |
593 | } | 576 | } |
594 | 577 | ||
595 | /* | 578 | /* |
596 | ** point the PortP->Phbs at the real Phbs | 579 | ** point the PortP->Phbs at the real Phbs |
597 | */ | 580 | */ |
598 | for ( PortN=p->RIOFirstPortsMapped; | 581 | for (PortN = p->RIOFirstPortsMapped; PortN < p->RIOLastPortsMapped + PORTS_PER_RTA; PortN++) { |
599 | PortN<p->RIOLastPortsMapped+PORTS_PER_RTA; PortN++ ) { | 582 | if (p->RIOPortp[PortN]->HostP == HostP) { |
600 | if ( p->RIOPortp[PortN]->HostP == HostP ) { | ||
601 | struct Port *PortP = p->RIOPortp[PortN]; | 583 | struct Port *PortP = p->RIOPortp[PortN]; |
602 | struct PHB *PhbP; | 584 | struct PHB *PhbP; |
603 | /* int oldspl; */ | 585 | /* int oldspl; */ |
604 | 586 | ||
605 | if ( !PortP->Mapped ) | 587 | if (!PortP->Mapped) |
606 | continue; | 588 | continue; |
607 | 589 | ||
608 | PhbP = &HostP->PhbP[PortP->HostPort]; | 590 | PhbP = &HostP->PhbP[PortP->HostPort]; |
@@ -610,40 +592,40 @@ register struct DownLoad *rbp; | |||
610 | 592 | ||
611 | PortP->PhbP = PhbP; | 593 | PortP->PhbP = PhbP; |
612 | 594 | ||
613 | PortP->TxAdd = (WORD *)RIO_PTR(Cad,RWORD(PhbP->tx_add)); | 595 | PortP->TxAdd = (WORD *) RIO_PTR(Cad, RWORD(PhbP->tx_add)); |
614 | PortP->TxStart = (WORD *)RIO_PTR(Cad,RWORD(PhbP->tx_start)); | 596 | PortP->TxStart = (WORD *) RIO_PTR(Cad, RWORD(PhbP->tx_start)); |
615 | PortP->TxEnd = (WORD *)RIO_PTR(Cad,RWORD(PhbP->tx_end)); | 597 | PortP->TxEnd = (WORD *) RIO_PTR(Cad, RWORD(PhbP->tx_end)); |
616 | PortP->RxRemove = (WORD *)RIO_PTR(Cad,RWORD(PhbP->rx_remove)); | 598 | PortP->RxRemove = (WORD *) RIO_PTR(Cad, RWORD(PhbP->rx_remove)); |
617 | PortP->RxStart = (WORD *)RIO_PTR(Cad,RWORD(PhbP->rx_start)); | 599 | PortP->RxStart = (WORD *) RIO_PTR(Cad, RWORD(PhbP->rx_start)); |
618 | PortP->RxEnd = (WORD *)RIO_PTR(Cad,RWORD(PhbP->rx_end)); | 600 | PortP->RxEnd = (WORD *) RIO_PTR(Cad, RWORD(PhbP->rx_end)); |
619 | 601 | ||
620 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | 602 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
621 | /* | 603 | /* |
622 | ** point the UnixRup at the base SysPort | 604 | ** point the UnixRup at the base SysPort |
623 | */ | 605 | */ |
624 | if ( !(PortN % PORTS_PER_RTA) ) | 606 | if (!(PortN % PORTS_PER_RTA)) |
625 | HostP->UnixRups[PortP->RupNum].BaseSysPort = PortN; | 607 | HostP->UnixRups[PortP->RupNum].BaseSysPort = PortN; |
626 | } | 608 | } |
627 | } | 609 | } |
628 | 610 | ||
629 | rio_dprintk (RIO_DEBUG_BOOT, "Set the card running... \n"); | 611 | rio_dprintk(RIO_DEBUG_BOOT, "Set the card running... \n"); |
630 | /* | 612 | /* |
631 | ** last thing - show the world that everything is in place | 613 | ** last thing - show the world that everything is in place |
632 | */ | 614 | */ |
633 | HostP->Flags &= ~RUN_STATE; | 615 | HostP->Flags &= ~RUN_STATE; |
634 | HostP->Flags |= RC_RUNNING; | 616 | HostP->Flags |= RC_RUNNING; |
635 | } | 617 | } |
636 | /* | 618 | /* |
637 | ** MPX always uses a poller. This is actually patched into the system | 619 | ** MPX always uses a poller. This is actually patched into the system |
638 | ** configuration and called directly from each clock tick. | 620 | ** configuration and called directly from each clock tick. |
639 | ** | 621 | ** |
640 | */ | 622 | */ |
641 | p->RIOPolling = 1; | 623 | p->RIOPolling = 1; |
642 | 624 | ||
643 | p->RIOSystemUp++; | 625 | p->RIOSystemUp++; |
644 | 626 | ||
645 | rio_dprintk (RIO_DEBUG_BOOT, "Done everything %x\n", HostP->Ivec); | 627 | rio_dprintk(RIO_DEBUG_BOOT, "Done everything %x\n", HostP->Ivec); |
646 | func_exit (); | 628 | func_exit(); |
647 | return 0; | 629 | return 0; |
648 | } | 630 | } |
649 | 631 | ||
@@ -653,23 +635,22 @@ register struct DownLoad *rbp; | |||
653 | ** Boot an RTA. If we have successfully processed this boot, then | 635 | ** Boot an RTA. If we have successfully processed this boot, then |
654 | ** return 1. If we havent, then return 0. | 636 | ** return 1. If we havent, then return 0. |
655 | */ | 637 | */ |
656 | int | 638 | int RIOBootRup(p, Rup, HostP, PacketP) |
657 | RIOBootRup( p, Rup, HostP, PacketP) | 639 | struct rio_info *p; |
658 | struct rio_info * p; | ||
659 | uint Rup; | 640 | uint Rup; |
660 | struct Host *HostP; | 641 | struct Host *HostP; |
661 | struct PKT *PacketP; | 642 | struct PKT *PacketP; |
662 | { | 643 | { |
663 | struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data; | 644 | struct PktCmd *PktCmdP = (struct PktCmd *) PacketP->data; |
664 | struct PktCmd_M *PktReplyP; | 645 | struct PktCmd_M *PktReplyP; |
665 | struct CmdBlk *CmdBlkP; | 646 | struct CmdBlk *CmdBlkP; |
666 | uint sequence; | 647 | uint sequence; |
667 | 648 | ||
668 | /* | 649 | /* |
669 | ** If we haven't been told what to boot, we can't boot it. | 650 | ** If we haven't been told what to boot, we can't boot it. |
670 | */ | 651 | */ |
671 | if ( p->RIONumBootPkts == 0 ) { | 652 | if (p->RIONumBootPkts == 0) { |
672 | rio_dprintk (RIO_DEBUG_BOOT, "No RTA code to download yet\n"); | 653 | rio_dprintk(RIO_DEBUG_BOOT, "No RTA code to download yet\n"); |
673 | return 0; | 654 | return 0; |
674 | } | 655 | } |
675 | 656 | ||
@@ -677,117 +658,111 @@ struct PKT *PacketP; | |||
677 | /* ShowPacket( DBG_BOOT, PacketP ); */ | 658 | /* ShowPacket( DBG_BOOT, PacketP ); */ |
678 | 659 | ||
679 | /* | 660 | /* |
680 | ** Special case of boot completed - if we get one of these then we | 661 | ** Special case of boot completed - if we get one of these then we |
681 | ** don't need a command block. For all other cases we do, so handle | 662 | ** don't need a command block. For all other cases we do, so handle |
682 | ** this first and then get a command block, then handle every other | 663 | ** this first and then get a command block, then handle every other |
683 | ** case, relinquishing the command block if disaster strikes! | 664 | ** case, relinquishing the command block if disaster strikes! |
684 | */ | 665 | */ |
685 | if ( (RBYTE(PacketP->len) & PKT_CMD_BIT) && | 666 | if ((RBYTE(PacketP->len) & PKT_CMD_BIT) && (RBYTE(PktCmdP->Command) == BOOT_COMPLETED)) |
686 | (RBYTE(PktCmdP->Command)==BOOT_COMPLETED) ) | 667 | return RIOBootComplete(p, HostP, Rup, PktCmdP); |
687 | return RIOBootComplete(p, HostP, Rup, PktCmdP ); | ||
688 | 668 | ||
689 | /* | 669 | /* |
690 | ** try to unhook a command block from the command free list. | 670 | ** try to unhook a command block from the command free list. |
691 | */ | 671 | */ |
692 | if ( !(CmdBlkP = RIOGetCmdBlk()) ) { | 672 | if (!(CmdBlkP = RIOGetCmdBlk())) { |
693 | rio_dprintk (RIO_DEBUG_BOOT, "No command blocks to boot RTA! come back later.\n"); | 673 | rio_dprintk(RIO_DEBUG_BOOT, "No command blocks to boot RTA! come back later.\n"); |
694 | return 0; | 674 | return 0; |
695 | } | 675 | } |
696 | 676 | ||
697 | /* | 677 | /* |
698 | ** Fill in the default info on the command block | 678 | ** Fill in the default info on the command block |
699 | */ | 679 | */ |
700 | CmdBlkP->Packet.dest_unit = Rup < (ushort)MAX_RUP ? Rup : 0; | 680 | CmdBlkP->Packet.dest_unit = Rup < (ushort) MAX_RUP ? Rup : 0; |
701 | CmdBlkP->Packet.dest_port = BOOT_RUP; | 681 | CmdBlkP->Packet.dest_port = BOOT_RUP; |
702 | CmdBlkP->Packet.src_unit = 0; | 682 | CmdBlkP->Packet.src_unit = 0; |
703 | CmdBlkP->Packet.src_port = BOOT_RUP; | 683 | CmdBlkP->Packet.src_port = BOOT_RUP; |
704 | 684 | ||
705 | CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL; | 685 | CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL; |
706 | PktReplyP = (struct PktCmd_M *)CmdBlkP->Packet.data; | 686 | PktReplyP = (struct PktCmd_M *) CmdBlkP->Packet.data; |
707 | 687 | ||
708 | /* | 688 | /* |
709 | ** process COMMANDS on the boot rup! | 689 | ** process COMMANDS on the boot rup! |
710 | */ | 690 | */ |
711 | if ( RBYTE(PacketP->len) & PKT_CMD_BIT ) { | 691 | if (RBYTE(PacketP->len) & PKT_CMD_BIT) { |
712 | /* | 692 | /* |
713 | ** We only expect one type of command - a BOOT_REQUEST! | 693 | ** We only expect one type of command - a BOOT_REQUEST! |
714 | */ | 694 | */ |
715 | if ( RBYTE(PktCmdP->Command) != BOOT_REQUEST ) { | 695 | if (RBYTE(PktCmdP->Command) != BOOT_REQUEST) { |
716 | rio_dprintk (RIO_DEBUG_BOOT, "Unexpected command %d on BOOT RUP %d of host %d\n", | 696 | rio_dprintk(RIO_DEBUG_BOOT, "Unexpected command %d on BOOT RUP %d of host %d\n", PktCmdP->Command, Rup, HostP - p->RIOHosts); |
717 | PktCmdP->Command,Rup,HostP-p->RIOHosts); | 697 | ShowPacket(DBG_BOOT, PacketP); |
718 | ShowPacket( DBG_BOOT, PacketP ); | 698 | RIOFreeCmdBlk(CmdBlkP); |
719 | RIOFreeCmdBlk( CmdBlkP ); | ||
720 | return 1; | 699 | return 1; |
721 | } | 700 | } |
722 | 701 | ||
723 | /* | 702 | /* |
724 | ** Build a Boot Sequence command block | 703 | ** Build a Boot Sequence command block |
725 | ** | 704 | ** |
726 | ** 02.03.1999 ARG - ESIL 0820 fix | 705 | ** 02.03.1999 ARG - ESIL 0820 fix |
727 | ** We no longer need to use "Boot Mode", we'll always allow | 706 | ** We no longer need to use "Boot Mode", we'll always allow |
728 | ** boot requests - the boot will not complete if the device | 707 | ** boot requests - the boot will not complete if the device |
729 | ** appears in the bindings table. | 708 | ** appears in the bindings table. |
730 | ** So, this conditional is not required ... | 709 | ** So, this conditional is not required ... |
731 | ** | 710 | ** |
732 | if (p->RIOBootMode == RC_BOOT_NONE) | 711 | if (p->RIOBootMode == RC_BOOT_NONE) |
733 | ** | 712 | ** |
734 | ** If the system is in slave mode, and a boot request is | 713 | ** If the system is in slave mode, and a boot request is |
735 | ** received, set command to BOOT_ABORT so that the boot | 714 | ** received, set command to BOOT_ABORT so that the boot |
736 | ** will not complete. | 715 | ** will not complete. |
737 | ** | 716 | ** |
738 | PktReplyP->Command = BOOT_ABORT; | 717 | PktReplyP->Command = BOOT_ABORT; |
739 | else | 718 | else |
740 | ** | 719 | ** |
741 | ** We'll just (always) set the command field in packet reply | 720 | ** We'll just (always) set the command field in packet reply |
742 | ** to allow an attempted boot sequence : | 721 | ** to allow an attempted boot sequence : |
743 | */ | 722 | */ |
744 | PktReplyP->Command = BOOT_SEQUENCE; | 723 | PktReplyP->Command = BOOT_SEQUENCE; |
745 | 724 | ||
746 | PktReplyP->BootSequence.NumPackets = p->RIONumBootPkts; | 725 | PktReplyP->BootSequence.NumPackets = p->RIONumBootPkts; |
747 | PktReplyP->BootSequence.LoadBase = p->RIOConf.RtaLoadBase; | 726 | PktReplyP->BootSequence.LoadBase = p->RIOConf.RtaLoadBase; |
748 | PktReplyP->BootSequence.CodeSize = p->RIOBootCount; | 727 | PktReplyP->BootSequence.CodeSize = p->RIOBootCount; |
749 | 728 | ||
750 | CmdBlkP->Packet.len = BOOT_SEQUENCE_LEN | PKT_CMD_BIT; | 729 | CmdBlkP->Packet.len = BOOT_SEQUENCE_LEN | PKT_CMD_BIT; |
751 | 730 | ||
752 | bcopy("BOOT",(void *)&CmdBlkP->Packet.data[BOOT_SEQUENCE_LEN],4); | 731 | bcopy("BOOT", (void *) &CmdBlkP->Packet.data[BOOT_SEQUENCE_LEN], 4); |
753 | 732 | ||
754 | rio_dprintk (RIO_DEBUG_BOOT, "Boot RTA on Host %d Rup %d - %d (0x%x) packets to 0x%x\n", | 733 | rio_dprintk(RIO_DEBUG_BOOT, "Boot RTA on Host %d Rup %d - %d (0x%x) packets to 0x%x\n", HostP - p->RIOHosts, Rup, p->RIONumBootPkts, p->RIONumBootPkts, p->RIOConf.RtaLoadBase); |
755 | HostP-p->RIOHosts, Rup, p->RIONumBootPkts, p->RIONumBootPkts, | ||
756 | p->RIOConf.RtaLoadBase); | ||
757 | 734 | ||
758 | /* | 735 | /* |
759 | ** If this host is in slave mode, send the RTA an invalid boot | 736 | ** If this host is in slave mode, send the RTA an invalid boot |
760 | ** sequence command block to force it to kill the boot. We wait | 737 | ** sequence command block to force it to kill the boot. We wait |
761 | ** for half a second before sending this packet to prevent the RTA | 738 | ** for half a second before sending this packet to prevent the RTA |
762 | ** attempting to boot too often. The master host should then grab | 739 | ** attempting to boot too often. The master host should then grab |
763 | ** the RTA and make it its own. | 740 | ** the RTA and make it its own. |
764 | */ | 741 | */ |
765 | p->RIOBooting++; | 742 | p->RIOBooting++; |
766 | RIOQueueCmdBlk( HostP, Rup, CmdBlkP ); | 743 | RIOQueueCmdBlk(HostP, Rup, CmdBlkP); |
767 | return 1; | 744 | return 1; |
768 | } | 745 | } |
769 | 746 | ||
770 | /* | 747 | /* |
771 | ** It is a request for boot data. | 748 | ** It is a request for boot data. |
772 | */ | 749 | */ |
773 | sequence = RWORD(PktCmdP->Sequence); | 750 | sequence = RWORD(PktCmdP->Sequence); |
774 | 751 | ||
775 | rio_dprintk (RIO_DEBUG_BOOT, "Boot block %d on Host %d Rup%d\n",sequence,HostP-p->RIOHosts,Rup); | 752 | rio_dprintk(RIO_DEBUG_BOOT, "Boot block %d on Host %d Rup%d\n", sequence, HostP - p->RIOHosts, Rup); |
776 | 753 | ||
777 | if ( sequence >= p->RIONumBootPkts ) { | 754 | if (sequence >= p->RIONumBootPkts) { |
778 | rio_dprintk (RIO_DEBUG_BOOT, "Got a request for packet %d, max is %d\n", sequence, | 755 | rio_dprintk(RIO_DEBUG_BOOT, "Got a request for packet %d, max is %d\n", sequence, p->RIONumBootPkts); |
779 | p->RIONumBootPkts); | 756 | ShowPacket(DBG_BOOT, PacketP); |
780 | ShowPacket( DBG_BOOT, PacketP ); | ||
781 | } | 757 | } |
782 | 758 | ||
783 | PktReplyP->Sequence = sequence; | 759 | PktReplyP->Sequence = sequence; |
784 | 760 | ||
785 | bcopy( p->RIOBootPackets[ p->RIONumBootPkts - sequence - 1 ], | 761 | bcopy(p->RIOBootPackets[p->RIONumBootPkts - sequence - 1], PktReplyP->BootData, RTA_BOOT_DATA_SIZE); |
786 | PktReplyP->BootData, RTA_BOOT_DATA_SIZE ); | ||
787 | 762 | ||
788 | CmdBlkP->Packet.len = PKT_MAX_DATA_LEN; | 763 | CmdBlkP->Packet.len = PKT_MAX_DATA_LEN; |
789 | ShowPacket( DBG_BOOT, &CmdBlkP->Packet ); | 764 | ShowPacket(DBG_BOOT, &CmdBlkP->Packet); |
790 | RIOQueueCmdBlk( HostP, Rup, CmdBlkP ); | 765 | RIOQueueCmdBlk(HostP, Rup, CmdBlkP); |
791 | return 1; | 766 | return 1; |
792 | } | 767 | } |
793 | 768 | ||
@@ -797,422 +772,348 @@ struct PKT *PacketP; | |||
797 | ** If booted by an RTA, HostP->Mapping[Rup].RtaUniqueNum is the booting RTA. | 772 | ** If booted by an RTA, HostP->Mapping[Rup].RtaUniqueNum is the booting RTA. |
798 | ** RtaUniq is the booted RTA. | 773 | ** RtaUniq is the booted RTA. |
799 | */ | 774 | */ |
800 | static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, struct PktCmd *PktCmdP ) | 775 | static int RIOBootComplete(struct rio_info *p, struct Host *HostP, uint Rup, struct PktCmd *PktCmdP) |
801 | { | 776 | { |
802 | struct Map *MapP = NULL; | 777 | struct Map *MapP = NULL; |
803 | struct Map *MapP2 = NULL; | 778 | struct Map *MapP2 = NULL; |
804 | int Flag; | 779 | int Flag; |
805 | int found; | 780 | int found; |
806 | int host, rta; | 781 | int host, rta; |
807 | int EmptySlot = -1; | 782 | int EmptySlot = -1; |
808 | int entry, entry2; | 783 | int entry, entry2; |
809 | char *MyType, *MyName; | 784 | char *MyType, *MyName; |
810 | uint MyLink; | 785 | uint MyLink; |
811 | ushort RtaType; | 786 | ushort RtaType; |
812 | uint RtaUniq = (RBYTE(PktCmdP->UniqNum[0])) + | 787 | uint RtaUniq = (RBYTE(PktCmdP->UniqNum[0])) + (RBYTE(PktCmdP->UniqNum[1]) << 8) + (RBYTE(PktCmdP->UniqNum[2]) << 16) + (RBYTE(PktCmdP->UniqNum[3]) << 24); |
813 | (RBYTE(PktCmdP->UniqNum[1]) << 8) + | ||
814 | (RBYTE(PktCmdP->UniqNum[2]) << 16) + | ||
815 | (RBYTE(PktCmdP->UniqNum[3]) << 24); | ||
816 | 788 | ||
817 | /* Was RIOBooting-- . That's bad. If an RTA sends two of them, the | 789 | /* Was RIOBooting-- . That's bad. If an RTA sends two of them, the |
818 | driver will never think that the RTA has booted... -- REW */ | 790 | driver will never think that the RTA has booted... -- REW */ |
819 | p->RIOBooting = 0; | 791 | p->RIOBooting = 0; |
820 | 792 | ||
821 | rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot completed - BootInProgress now %d\n", p->RIOBooting); | 793 | rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot completed - BootInProgress now %d\n", p->RIOBooting); |
822 | 794 | ||
823 | /* | 795 | /* |
824 | ** Determine type of unit (16/8 port RTA). | 796 | ** Determine type of unit (16/8 port RTA). |
825 | */ | 797 | */ |
826 | RtaType = GetUnitType(RtaUniq); | 798 | RtaType = GetUnitType(RtaUniq); |
827 | if ( Rup >= (ushort)MAX_RUP ) { | 799 | if (Rup >= (ushort) MAX_RUP) { |
828 | rio_dprintk (RIO_DEBUG_BOOT, "RIO: Host %s has booted an RTA(%d) on link %c\n", | 800 | rio_dprintk(RIO_DEBUG_BOOT, "RIO: Host %s has booted an RTA(%d) on link %c\n", HostP->Name, 8 * RtaType, RBYTE(PktCmdP->LinkNum) + 'A'); |
829 | HostP->Name, 8 * RtaType, RBYTE(PktCmdP->LinkNum)+'A'); | ||
830 | } else { | 801 | } else { |
831 | rio_dprintk (RIO_DEBUG_BOOT, "RIO: RTA %s has booted an RTA(%d) on link %c\n", | 802 | rio_dprintk(RIO_DEBUG_BOOT, "RIO: RTA %s has booted an RTA(%d) on link %c\n", HostP->Mapping[Rup].Name, 8 * RtaType, RBYTE(PktCmdP->LinkNum) + 'A'); |
832 | HostP->Mapping[Rup].Name, 8 * RtaType, | ||
833 | RBYTE(PktCmdP->LinkNum)+'A'); | ||
834 | } | 803 | } |
835 | 804 | ||
836 | rio_dprintk (RIO_DEBUG_BOOT, "UniqNum is 0x%x\n",RtaUniq); | 805 | rio_dprintk(RIO_DEBUG_BOOT, "UniqNum is 0x%x\n", RtaUniq); |
837 | 806 | ||
838 | if ( ( RtaUniq == 0x00000000 ) || ( RtaUniq == 0xffffffff ) ) | 807 | if ((RtaUniq == 0x00000000) || (RtaUniq == 0xffffffff)) { |
839 | { | 808 | rio_dprintk(RIO_DEBUG_BOOT, "Illegal RTA Uniq Number\n"); |
840 | rio_dprintk (RIO_DEBUG_BOOT, "Illegal RTA Uniq Number\n"); | 809 | return TRUE; |
841 | return TRUE; | ||
842 | } | 810 | } |
843 | 811 | ||
844 | /* | 812 | /* |
845 | ** If this RTA has just booted an RTA which doesn't belong to this | 813 | ** If this RTA has just booted an RTA which doesn't belong to this |
846 | ** system, or the system is in slave mode, do not attempt to create | 814 | ** system, or the system is in slave mode, do not attempt to create |
847 | ** a new table entry for it. | 815 | ** a new table entry for it. |
848 | */ | 816 | */ |
849 | if (!RIOBootOk(p, HostP, RtaUniq)) | 817 | if (!RIOBootOk(p, HostP, RtaUniq)) { |
850 | { | 818 | MyLink = RBYTE(PktCmdP->LinkNum); |
851 | MyLink = RBYTE(PktCmdP->LinkNum); | 819 | if (Rup < (ushort) MAX_RUP) { |
852 | if (Rup < (ushort) MAX_RUP) | 820 | /* |
853 | { | 821 | ** RtaUniq was clone booted (by this RTA). Instruct this RTA |
854 | /* | 822 | ** to hold off further attempts to boot on this link for 30 |
855 | ** RtaUniq was clone booted (by this RTA). Instruct this RTA | 823 | ** seconds. |
856 | ** to hold off further attempts to boot on this link for 30 | 824 | */ |
857 | ** seconds. | 825 | if (RIOSuspendBootRta(HostP, HostP->Mapping[Rup].ID, MyLink)) { |
858 | */ | 826 | rio_dprintk(RIO_DEBUG_BOOT, "RTA failed to suspend booting on link %c\n", 'A' + MyLink); |
859 | if (RIOSuspendBootRta(HostP, HostP->Mapping[Rup].ID, MyLink)) | 827 | } |
860 | { | 828 | } else { |
861 | rio_dprintk (RIO_DEBUG_BOOT, "RTA failed to suspend booting on link %c\n", | 829 | /* |
862 | 'A' + MyLink); | 830 | ** RtaUniq was booted by this host. Set the booting link |
831 | ** to hold off for 30 seconds to give another unit a | ||
832 | ** chance to boot it. | ||
833 | */ | ||
834 | WWORD(HostP->LinkStrP[MyLink].WaitNoBoot, 30); | ||
863 | } | 835 | } |
864 | } | 836 | rio_dprintk(RIO_DEBUG_BOOT, "RTA %x not owned - suspend booting down link %c on unit %x\n", RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum); |
865 | else | 837 | return TRUE; |
866 | { | ||
867 | /* | ||
868 | ** RtaUniq was booted by this host. Set the booting link | ||
869 | ** to hold off for 30 seconds to give another unit a | ||
870 | ** chance to boot it. | ||
871 | */ | ||
872 | WWORD(HostP->LinkStrP[MyLink].WaitNoBoot, 30); | ||
873 | } | ||
874 | rio_dprintk (RIO_DEBUG_BOOT, "RTA %x not owned - suspend booting down link %c on unit %x\n", | ||
875 | RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum); | ||
876 | return TRUE; | ||
877 | } | 838 | } |
878 | 839 | ||
879 | /* | 840 | /* |
880 | ** Check for a SLOT_IN_USE entry for this RTA attached to the | 841 | ** Check for a SLOT_IN_USE entry for this RTA attached to the |
881 | ** current host card in the driver table. | 842 | ** current host card in the driver table. |
882 | ** | 843 | ** |
883 | ** If it exists, make a note that we have booted it. Other parts of | 844 | ** If it exists, make a note that we have booted it. Other parts of |
884 | ** the driver are interested in this information at a later date, | 845 | ** the driver are interested in this information at a later date, |
885 | ** in particular when the booting RTA asks for an ID for this unit, | 846 | ** in particular when the booting RTA asks for an ID for this unit, |
886 | ** we must have set the BOOTED flag, and the NEWBOOT flag is used | 847 | ** we must have set the BOOTED flag, and the NEWBOOT flag is used |
887 | ** to force an open on any ports that where previously open on this | 848 | ** to force an open on any ports that where previously open on this |
888 | ** unit. | 849 | ** unit. |
889 | */ | 850 | */ |
890 | for ( entry=0; entry<MAX_RUP; entry++ ) | 851 | for (entry = 0; entry < MAX_RUP; entry++) { |
891 | { | 852 | uint sysport; |
892 | uint sysport; | 853 | |
893 | 854 | if ((HostP->Mapping[entry].Flags & SLOT_IN_USE) && (HostP->Mapping[entry].RtaUniqueNum == RtaUniq)) { | |
894 | if ((HostP->Mapping[entry].Flags & SLOT_IN_USE) && | 855 | HostP->Mapping[entry].Flags |= RTA_BOOTED | RTA_NEWBOOT; |
895 | (HostP->Mapping[entry].RtaUniqueNum==RtaUniq)) | ||
896 | { | ||
897 | HostP->Mapping[entry].Flags |= RTA_BOOTED|RTA_NEWBOOT; | ||
898 | #ifdef NEED_TO_FIX | 856 | #ifdef NEED_TO_FIX |
899 | RIO_SV_BROADCAST(HostP->svFlags[entry]); | 857 | RIO_SV_BROADCAST(HostP->svFlags[entry]); |
900 | #endif | 858 | #endif |
901 | if ( (sysport=HostP->Mapping[entry].SysPort) != NO_PORT ) | 859 | if ((sysport = HostP->Mapping[entry].SysPort) != NO_PORT) { |
902 | { | 860 | if (sysport < p->RIOFirstPortsBooted) |
903 | if ( sysport < p->RIOFirstPortsBooted ) | 861 | p->RIOFirstPortsBooted = sysport; |
904 | p->RIOFirstPortsBooted = sysport; | 862 | if (sysport > p->RIOLastPortsBooted) |
905 | if ( sysport > p->RIOLastPortsBooted ) | 863 | p->RIOLastPortsBooted = sysport; |
906 | p->RIOLastPortsBooted = sysport; | 864 | /* |
907 | /* | 865 | ** For a 16 port RTA, check the second bank of 8 ports |
908 | ** For a 16 port RTA, check the second bank of 8 ports | 866 | */ |
909 | */ | 867 | if (RtaType == TYPE_RTA16) { |
910 | if (RtaType == TYPE_RTA16) | 868 | entry2 = HostP->Mapping[entry].ID2 - 1; |
911 | { | 869 | HostP->Mapping[entry2].Flags |= RTA_BOOTED | RTA_NEWBOOT; |
912 | entry2 = HostP->Mapping[entry].ID2 - 1; | ||
913 | HostP->Mapping[entry2].Flags |= RTA_BOOTED|RTA_NEWBOOT; | ||
914 | #ifdef NEED_TO_FIX | 870 | #ifdef NEED_TO_FIX |
915 | RIO_SV_BROADCAST(HostP->svFlags[entry2]); | 871 | RIO_SV_BROADCAST(HostP->svFlags[entry2]); |
916 | #endif | 872 | #endif |
917 | sysport = HostP->Mapping[entry2].SysPort; | 873 | sysport = HostP->Mapping[entry2].SysPort; |
918 | if ( sysport < p->RIOFirstPortsBooted ) | 874 | if (sysport < p->RIOFirstPortsBooted) |
919 | p->RIOFirstPortsBooted = sysport; | 875 | p->RIOFirstPortsBooted = sysport; |
920 | if ( sysport > p->RIOLastPortsBooted ) | 876 | if (sysport > p->RIOLastPortsBooted) |
921 | p->RIOLastPortsBooted = sysport; | 877 | p->RIOLastPortsBooted = sysport; |
922 | } | 878 | } |
923 | } | 879 | } |
924 | if (RtaType == TYPE_RTA16) { | 880 | if (RtaType == TYPE_RTA16) { |
925 | rio_dprintk (RIO_DEBUG_BOOT, "RTA will be given IDs %d+%d\n", | 881 | rio_dprintk(RIO_DEBUG_BOOT, "RTA will be given IDs %d+%d\n", entry + 1, entry2 + 1); |
926 | entry+1, entry2+1); | 882 | } else { |
927 | } else { | 883 | rio_dprintk(RIO_DEBUG_BOOT, "RTA will be given ID %d\n", entry + 1); |
928 | rio_dprintk (RIO_DEBUG_BOOT, "RTA will be given ID %d\n",entry+1); | 884 | } |
885 | return TRUE; | ||
929 | } | 886 | } |
930 | return TRUE; | ||
931 | } | ||
932 | } | 887 | } |
933 | 888 | ||
934 | rio_dprintk (RIO_DEBUG_BOOT, "RTA not configured for this host\n"); | 889 | rio_dprintk(RIO_DEBUG_BOOT, "RTA not configured for this host\n"); |
935 | 890 | ||
936 | if ( Rup >= (ushort)MAX_RUP ) | 891 | if (Rup >= (ushort) MAX_RUP) { |
937 | { | 892 | /* |
938 | /* | 893 | ** It was a host that did the booting |
939 | ** It was a host that did the booting | 894 | */ |
940 | */ | 895 | MyType = "Host"; |
941 | MyType = "Host"; | 896 | MyName = HostP->Name; |
942 | MyName = HostP->Name; | 897 | } else { |
943 | } | 898 | /* |
944 | else | 899 | ** It was an RTA that did the booting |
945 | { | 900 | */ |
946 | /* | 901 | MyType = "RTA"; |
947 | ** It was an RTA that did the booting | 902 | MyName = HostP->Mapping[Rup].Name; |
948 | */ | ||
949 | MyType = "RTA"; | ||
950 | MyName = HostP->Mapping[Rup].Name; | ||
951 | } | 903 | } |
952 | MyLink = RBYTE(PktCmdP->LinkNum); | 904 | MyLink = RBYTE(PktCmdP->LinkNum); |
953 | 905 | ||
954 | /* | 906 | /* |
955 | ** There is no SLOT_IN_USE entry for this RTA attached to the current | 907 | ** There is no SLOT_IN_USE entry for this RTA attached to the current |
956 | ** host card in the driver table. | 908 | ** host card in the driver table. |
957 | ** | 909 | ** |
958 | ** Check for a SLOT_TENTATIVE entry for this RTA attached to the | 910 | ** Check for a SLOT_TENTATIVE entry for this RTA attached to the |
959 | ** current host card in the driver table. | 911 | ** current host card in the driver table. |
960 | ** | 912 | ** |
961 | ** If we find one, then we re-use that slot. | 913 | ** If we find one, then we re-use that slot. |
962 | */ | 914 | */ |
963 | for ( entry=0; entry<MAX_RUP; entry++ ) | 915 | for (entry = 0; entry < MAX_RUP; entry++) { |
964 | { | 916 | if ((HostP->Mapping[entry].Flags & SLOT_TENTATIVE) && (HostP->Mapping[entry].RtaUniqueNum == RtaUniq)) { |
965 | if ( (HostP->Mapping[entry].Flags & SLOT_TENTATIVE) && | 917 | if (RtaType == TYPE_RTA16) { |
966 | (HostP->Mapping[entry].RtaUniqueNum == RtaUniq) ) | 918 | entry2 = HostP->Mapping[entry].ID2 - 1; |
967 | { | 919 | if ((HostP->Mapping[entry2].Flags & SLOT_TENTATIVE) && (HostP->Mapping[entry2].RtaUniqueNum == RtaUniq)) |
968 | if (RtaType == TYPE_RTA16) | 920 | rio_dprintk(RIO_DEBUG_BOOT, "Found previous tentative slots (%d+%d)\n", entry, entry2); |
969 | { | 921 | else |
970 | entry2 = HostP->Mapping[entry].ID2 - 1; | 922 | continue; |
971 | if ( (HostP->Mapping[entry2].Flags & SLOT_TENTATIVE) && | 923 | } else |
972 | (HostP->Mapping[entry2].RtaUniqueNum == RtaUniq) ) | 924 | rio_dprintk(RIO_DEBUG_BOOT, "Found previous tentative slot (%d)\n", entry); |
973 | rio_dprintk (RIO_DEBUG_BOOT, "Found previous tentative slots (%d+%d)\n", | 925 | if (!p->RIONoMessage) |
974 | entry, entry2); | 926 | cprintf("RTA connected to %s '%s' (%c) not configured.\n", MyType, MyName, MyLink + 'A'); |
975 | else | 927 | return TRUE; |
976 | continue; | ||
977 | } | 928 | } |
978 | else | ||
979 | rio_dprintk (RIO_DEBUG_BOOT, "Found previous tentative slot (%d)\n",entry); | ||
980 | if (! p->RIONoMessage) | ||
981 | cprintf("RTA connected to %s '%s' (%c) not configured.\n",MyType,MyName,MyLink+'A'); | ||
982 | return TRUE; | ||
983 | } | ||
984 | } | 929 | } |
985 | 930 | ||
986 | /* | 931 | /* |
987 | ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA | 932 | ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA |
988 | ** attached to the current host card in the driver table. | 933 | ** attached to the current host card in the driver table. |
989 | ** | 934 | ** |
990 | ** Check if there is a SLOT_IN_USE or SLOT_TENTATIVE entry on another | 935 | ** Check if there is a SLOT_IN_USE or SLOT_TENTATIVE entry on another |
991 | ** host for this RTA in the driver table. | 936 | ** host for this RTA in the driver table. |
992 | ** | 937 | ** |
993 | ** For a SLOT_IN_USE entry on another host, we need to delete the RTA | 938 | ** For a SLOT_IN_USE entry on another host, we need to delete the RTA |
994 | ** entry from the other host and add it to this host (using some of | 939 | ** entry from the other host and add it to this host (using some of |
995 | ** the functions from table.c which do this). | 940 | ** the functions from table.c which do this). |
996 | ** For a SLOT_TENTATIVE entry on another host, we must cope with the | 941 | ** For a SLOT_TENTATIVE entry on another host, we must cope with the |
997 | ** following scenario: | 942 | ** following scenario: |
998 | ** | 943 | ** |
999 | ** + Plug 8 port RTA into host A. (This creates SLOT_TENTATIVE entry | 944 | ** + Plug 8 port RTA into host A. (This creates SLOT_TENTATIVE entry |
1000 | ** in table) | 945 | ** in table) |
1001 | ** + Unplug RTA and plug into host B. (We now have 2 SLOT_TENTATIVE | 946 | ** + Unplug RTA and plug into host B. (We now have 2 SLOT_TENTATIVE |
1002 | ** entries) | 947 | ** entries) |
1003 | ** + Configure RTA on host B. (This slot now becomes SLOT_IN_USE) | 948 | ** + Configure RTA on host B. (This slot now becomes SLOT_IN_USE) |
1004 | ** + Unplug RTA and plug back into host A. | 949 | ** + Unplug RTA and plug back into host A. |
1005 | ** + Configure RTA on host A. We now have the same RTA configured | 950 | ** + Configure RTA on host A. We now have the same RTA configured |
1006 | ** with different ports on two different hosts. | 951 | ** with different ports on two different hosts. |
1007 | */ | 952 | */ |
1008 | rio_dprintk (RIO_DEBUG_BOOT, "Have we seen RTA %x before?\n", RtaUniq ); | 953 | rio_dprintk(RIO_DEBUG_BOOT, "Have we seen RTA %x before?\n", RtaUniq); |
1009 | found = 0; | 954 | found = 0; |
1010 | Flag = 0; /* Convince the compiler this variable is initialized */ | 955 | Flag = 0; /* Convince the compiler this variable is initialized */ |
1011 | for ( host = 0; !found && (host < p->RIONumHosts); host++ ) | 956 | for (host = 0; !found && (host < p->RIONumHosts); host++) { |
1012 | { | 957 | for (rta = 0; rta < MAX_RUP; rta++) { |
1013 | for ( rta=0; rta<MAX_RUP; rta++ ) | 958 | if ((p->RIOHosts[host].Mapping[rta].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) && (p->RIOHosts[host].Mapping[rta].RtaUniqueNum == RtaUniq)) { |
1014 | { | 959 | Flag = p->RIOHosts[host].Mapping[rta].Flags; |
1015 | if ((p->RIOHosts[host].Mapping[rta].Flags & | 960 | MapP = &p->RIOHosts[host].Mapping[rta]; |
1016 | (SLOT_IN_USE | SLOT_TENTATIVE)) && | 961 | if (RtaType == TYPE_RTA16) { |
1017 | (p->RIOHosts[host].Mapping[rta].RtaUniqueNum==RtaUniq)) | 962 | MapP2 = &p->RIOHosts[host].Mapping[MapP->ID2 - 1]; |
1018 | { | 963 | rio_dprintk(RIO_DEBUG_BOOT, "This RTA is units %d+%d from host %s\n", rta + 1, MapP->ID2, p->RIOHosts[host].Name); |
1019 | Flag = p->RIOHosts[host].Mapping[rta].Flags; | 964 | } else |
1020 | MapP = &p->RIOHosts[host].Mapping[rta]; | 965 | rio_dprintk(RIO_DEBUG_BOOT, "This RTA is unit %d from host %s\n", rta + 1, p->RIOHosts[host].Name); |
1021 | if (RtaType == TYPE_RTA16) | 966 | found = 1; |
1022 | { | 967 | break; |
1023 | MapP2 = &p->RIOHosts[host].Mapping[MapP->ID2 - 1]; | 968 | } |
1024 | rio_dprintk (RIO_DEBUG_BOOT, "This RTA is units %d+%d from host %s\n", | ||
1025 | rta+1, MapP->ID2, p->RIOHosts[host].Name); | ||
1026 | } | ||
1027 | else | ||
1028 | rio_dprintk (RIO_DEBUG_BOOT, "This RTA is unit %d from host %s\n", | ||
1029 | rta+1, p->RIOHosts[host].Name); | ||
1030 | found = 1; | ||
1031 | break; | ||
1032 | } | 969 | } |
1033 | } | ||
1034 | } | 970 | } |
1035 | 971 | ||
1036 | /* | 972 | /* |
1037 | ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA | 973 | ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA |
1038 | ** attached to the current host card in the driver table. | 974 | ** attached to the current host card in the driver table. |
1039 | ** | 975 | ** |
1040 | ** If we have not found a SLOT_IN_USE or SLOT_TENTATIVE entry on | 976 | ** If we have not found a SLOT_IN_USE or SLOT_TENTATIVE entry on |
1041 | ** another host for this RTA in the driver table... | 977 | ** another host for this RTA in the driver table... |
1042 | ** | 978 | ** |
1043 | ** Check for a SLOT_IN_USE entry for this RTA in the config table. | 979 | ** Check for a SLOT_IN_USE entry for this RTA in the config table. |
1044 | */ | 980 | */ |
1045 | if ( !MapP ) | 981 | if (!MapP) { |
1046 | { | 982 | rio_dprintk(RIO_DEBUG_BOOT, "Look for RTA %x in RIOSavedTable\n", RtaUniq); |
1047 | rio_dprintk (RIO_DEBUG_BOOT, "Look for RTA %x in RIOSavedTable\n",RtaUniq); | 983 | for (rta = 0; rta < TOTAL_MAP_ENTRIES; rta++) { |
1048 | for ( rta=0; rta < TOTAL_MAP_ENTRIES; rta++ ) | 984 | rio_dprintk(RIO_DEBUG_BOOT, "Check table entry %d (%x)", rta, p->RIOSavedTable[rta].RtaUniqueNum); |
1049 | { | 985 | |
1050 | rio_dprintk (RIO_DEBUG_BOOT, "Check table entry %d (%x)", | 986 | if ((p->RIOSavedTable[rta].Flags & SLOT_IN_USE) && (p->RIOSavedTable[rta].RtaUniqueNum == RtaUniq)) { |
1051 | rta, | 987 | MapP = &p->RIOSavedTable[rta]; |
1052 | p->RIOSavedTable[rta].RtaUniqueNum); | 988 | Flag = p->RIOSavedTable[rta].Flags; |
1053 | 989 | if (RtaType == TYPE_RTA16) { | |
1054 | if ( (p->RIOSavedTable[rta].Flags & SLOT_IN_USE) && | 990 | for (entry2 = rta + 1; entry2 < TOTAL_MAP_ENTRIES; entry2++) { |
1055 | (p->RIOSavedTable[rta].RtaUniqueNum == RtaUniq) ) | 991 | if (p->RIOSavedTable[entry2].RtaUniqueNum == RtaUniq) |
1056 | { | 992 | break; |
1057 | MapP = &p->RIOSavedTable[rta]; | 993 | } |
1058 | Flag = p->RIOSavedTable[rta].Flags; | 994 | MapP2 = &p->RIOSavedTable[entry2]; |
1059 | if (RtaType == TYPE_RTA16) | 995 | rio_dprintk(RIO_DEBUG_BOOT, "This RTA is from table entries %d+%d\n", rta, entry2); |
1060 | { | 996 | } else |
1061 | for (entry2 = rta + 1; entry2 < TOTAL_MAP_ENTRIES; | 997 | rio_dprintk(RIO_DEBUG_BOOT, "This RTA is from table entry %d\n", rta); |
1062 | entry2++) | 998 | break; |
1063 | { | 999 | } |
1064 | if (p->RIOSavedTable[entry2].RtaUniqueNum == RtaUniq) | ||
1065 | break; | ||
1066 | } | ||
1067 | MapP2 = &p->RIOSavedTable[entry2]; | ||
1068 | rio_dprintk (RIO_DEBUG_BOOT, "This RTA is from table entries %d+%d\n", | ||
1069 | rta, entry2); | ||
1070 | } | ||
1071 | else | ||
1072 | rio_dprintk (RIO_DEBUG_BOOT, "This RTA is from table entry %d\n", rta); | ||
1073 | break; | ||
1074 | } | 1000 | } |
1075 | } | ||
1076 | } | 1001 | } |
1077 | 1002 | ||
1078 | /* | 1003 | /* |
1079 | ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA | 1004 | ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA |
1080 | ** attached to the current host card in the driver table. | 1005 | ** attached to the current host card in the driver table. |
1081 | ** | 1006 | ** |
1082 | ** We may have found a SLOT_IN_USE entry on another host for this | 1007 | ** We may have found a SLOT_IN_USE entry on another host for this |
1083 | ** RTA in the config table, or a SLOT_IN_USE or SLOT_TENTATIVE entry | 1008 | ** RTA in the config table, or a SLOT_IN_USE or SLOT_TENTATIVE entry |
1084 | ** on another host for this RTA in the driver table. | 1009 | ** on another host for this RTA in the driver table. |
1085 | ** | 1010 | ** |
1086 | ** Check the driver table for room to fit this newly discovered RTA. | 1011 | ** Check the driver table for room to fit this newly discovered RTA. |
1087 | ** RIOFindFreeID() first looks for free slots and if it does not | 1012 | ** RIOFindFreeID() first looks for free slots and if it does not |
1088 | ** find any free slots it will then attempt to oust any | 1013 | ** find any free slots it will then attempt to oust any |
1089 | ** tentative entry in the table. | 1014 | ** tentative entry in the table. |
1090 | */ | 1015 | */ |
1091 | EmptySlot = 1; | 1016 | EmptySlot = 1; |
1092 | if (RtaType == TYPE_RTA16) | 1017 | if (RtaType == TYPE_RTA16) { |
1093 | { | 1018 | if (RIOFindFreeID(p, HostP, &entry, &entry2) == 0) { |
1094 | if (RIOFindFreeID(p, HostP, &entry, &entry2) == 0) | 1019 | RIODefaultName(p, HostP, entry); |
1095 | { | 1020 | FillSlot(entry, entry2, RtaUniq, HostP); |
1096 | RIODefaultName(p, HostP, entry); | 1021 | EmptySlot = 0; |
1097 | FillSlot(entry, entry2, RtaUniq, HostP); | 1022 | } |
1098 | EmptySlot = 0; | 1023 | } else { |
1099 | } | 1024 | if (RIOFindFreeID(p, HostP, &entry, NULL) == 0) { |
1100 | } | 1025 | RIODefaultName(p, HostP, entry); |
1101 | else | 1026 | FillSlot(entry, 0, RtaUniq, HostP); |
1102 | { | 1027 | EmptySlot = 0; |
1103 | if (RIOFindFreeID(p, HostP, &entry, NULL) == 0) | 1028 | } |
1104 | { | ||
1105 | RIODefaultName(p, HostP, entry); | ||
1106 | FillSlot(entry, 0, RtaUniq, HostP); | ||
1107 | EmptySlot = 0; | ||
1108 | } | ||
1109 | } | 1029 | } |
1110 | 1030 | ||
1111 | /* | 1031 | /* |
1112 | ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA | 1032 | ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA |
1113 | ** attached to the current host card in the driver table. | 1033 | ** attached to the current host card in the driver table. |
1114 | ** | 1034 | ** |
1115 | ** If we found a SLOT_IN_USE entry on another host for this | 1035 | ** If we found a SLOT_IN_USE entry on another host for this |
1116 | ** RTA in the config or driver table, and there are enough free | 1036 | ** RTA in the config or driver table, and there are enough free |
1117 | ** slots in the driver table, then we need to move it over and | 1037 | ** slots in the driver table, then we need to move it over and |
1118 | ** delete it from the other host. | 1038 | ** delete it from the other host. |
1119 | ** If we found a SLOT_TENTATIVE entry on another host for this | 1039 | ** If we found a SLOT_TENTATIVE entry on another host for this |
1120 | ** RTA in the driver table, just delete the other host entry. | 1040 | ** RTA in the driver table, just delete the other host entry. |
1121 | */ | 1041 | */ |
1122 | if (EmptySlot == 0) | 1042 | if (EmptySlot == 0) { |
1123 | { | 1043 | if (MapP) { |
1124 | if ( MapP ) | 1044 | if (Flag & SLOT_IN_USE) { |
1125 | { | 1045 | rio_dprintk(RIO_DEBUG_BOOT, "This RTA configured on another host - move entry to current host (1)\n"); |
1126 | if (Flag & SLOT_IN_USE) | 1046 | HostP->Mapping[entry].SysPort = MapP->SysPort; |
1127 | { | 1047 | CCOPY(MapP->Name, HostP->Mapping[entry].Name, MAX_NAME_LEN); |
1128 | rio_dprintk (RIO_DEBUG_BOOT, | 1048 | HostP->Mapping[entry].Flags = SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT; |
1129 | "This RTA configured on another host - move entry to current host (1)\n"); | ||
1130 | HostP->Mapping[entry].SysPort = MapP->SysPort; | ||
1131 | CCOPY( MapP->Name, HostP->Mapping[entry].Name, MAX_NAME_LEN ); | ||
1132 | HostP->Mapping[entry].Flags = | ||
1133 | SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT; | ||
1134 | #ifdef NEED_TO_FIX | 1049 | #ifdef NEED_TO_FIX |
1135 | RIO_SV_BROADCAST(HostP->svFlags[entry]); | 1050 | RIO_SV_BROADCAST(HostP->svFlags[entry]); |
1136 | #endif | 1051 | #endif |
1137 | RIOReMapPorts( p, HostP, &HostP->Mapping[entry] ); | 1052 | RIOReMapPorts(p, HostP, &HostP->Mapping[entry]); |
1138 | if ( HostP->Mapping[entry].SysPort < p->RIOFirstPortsBooted ) | 1053 | if (HostP->Mapping[entry].SysPort < p->RIOFirstPortsBooted) |
1139 | p->RIOFirstPortsBooted = HostP->Mapping[entry].SysPort; | 1054 | p->RIOFirstPortsBooted = HostP->Mapping[entry].SysPort; |
1140 | if ( HostP->Mapping[entry].SysPort > p->RIOLastPortsBooted ) | 1055 | if (HostP->Mapping[entry].SysPort > p->RIOLastPortsBooted) |
1141 | p->RIOLastPortsBooted = HostP->Mapping[entry].SysPort; | 1056 | p->RIOLastPortsBooted = HostP->Mapping[entry].SysPort; |
1142 | rio_dprintk (RIO_DEBUG_BOOT, "SysPort %d, Name %s\n",(int)MapP->SysPort,MapP->Name); | 1057 | rio_dprintk(RIO_DEBUG_BOOT, "SysPort %d, Name %s\n", (int) MapP->SysPort, MapP->Name); |
1143 | } | 1058 | } else { |
1144 | else | 1059 | rio_dprintk(RIO_DEBUG_BOOT, "This RTA has a tentative entry on another host - delete that entry (1)\n"); |
1145 | { | 1060 | HostP->Mapping[entry].Flags = SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT; |
1146 | rio_dprintk (RIO_DEBUG_BOOT, | ||
1147 | "This RTA has a tentative entry on another host - delete that entry (1)\n"); | ||
1148 | HostP->Mapping[entry].Flags = | ||
1149 | SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT; | ||
1150 | #ifdef NEED_TO_FIX | 1061 | #ifdef NEED_TO_FIX |
1151 | RIO_SV_BROADCAST(HostP->svFlags[entry]); | 1062 | RIO_SV_BROADCAST(HostP->svFlags[entry]); |
1152 | #endif | 1063 | #endif |
1153 | } | 1064 | } |
1154 | if (RtaType == TYPE_RTA16) | 1065 | if (RtaType == TYPE_RTA16) { |
1155 | { | 1066 | if (Flag & SLOT_IN_USE) { |
1156 | if (Flag & SLOT_IN_USE) | 1067 | HostP->Mapping[entry2].Flags = SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; |
1157 | { | ||
1158 | HostP->Mapping[entry2].Flags = SLOT_IN_USE | | ||
1159 | RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; | ||
1160 | #ifdef NEED_TO_FIX | 1068 | #ifdef NEED_TO_FIX |
1161 | RIO_SV_BROADCAST(HostP->svFlags[entry2]); | 1069 | RIO_SV_BROADCAST(HostP->svFlags[entry2]); |
1162 | #endif | 1070 | #endif |
1163 | HostP->Mapping[entry2].SysPort = MapP2->SysPort; | 1071 | HostP->Mapping[entry2].SysPort = MapP2->SysPort; |
1164 | /* | 1072 | /* |
1165 | ** Map second block of ttys for 16 port RTA | 1073 | ** Map second block of ttys for 16 port RTA |
1166 | */ | 1074 | */ |
1167 | RIOReMapPorts( p, HostP, &HostP->Mapping[entry2] ); | 1075 | RIOReMapPorts(p, HostP, &HostP->Mapping[entry2]); |
1168 | if (HostP->Mapping[entry2].SysPort < p->RIOFirstPortsBooted) | 1076 | if (HostP->Mapping[entry2].SysPort < p->RIOFirstPortsBooted) |
1169 | p->RIOFirstPortsBooted = HostP->Mapping[entry2].SysPort; | 1077 | p->RIOFirstPortsBooted = HostP->Mapping[entry2].SysPort; |
1170 | if (HostP->Mapping[entry2].SysPort > p->RIOLastPortsBooted) | 1078 | if (HostP->Mapping[entry2].SysPort > p->RIOLastPortsBooted) |
1171 | p->RIOLastPortsBooted = HostP->Mapping[entry2].SysPort; | 1079 | p->RIOLastPortsBooted = HostP->Mapping[entry2].SysPort; |
1172 | rio_dprintk (RIO_DEBUG_BOOT, "SysPort %d, Name %s\n", | 1080 | rio_dprintk(RIO_DEBUG_BOOT, "SysPort %d, Name %s\n", (int) HostP->Mapping[entry2].SysPort, HostP->Mapping[entry].Name); |
1173 | (int)HostP->Mapping[entry2].SysPort, | 1081 | } else |
1174 | HostP->Mapping[entry].Name); | 1082 | HostP->Mapping[entry2].Flags = SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; |
1175 | } | ||
1176 | else | ||
1177 | HostP->Mapping[entry2].Flags = SLOT_TENTATIVE | | ||
1178 | RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; | ||
1179 | #ifdef NEED_TO_FIX | 1083 | #ifdef NEED_TO_FIX |
1180 | RIO_SV_BROADCAST(HostP->svFlags[entry2]); | 1084 | RIO_SV_BROADCAST(HostP->svFlags[entry2]); |
1181 | #endif | 1085 | #endif |
1182 | bzero( (caddr_t)MapP2, sizeof(struct Map) ); | 1086 | bzero((caddr_t) MapP2, sizeof(struct Map)); |
1183 | } | 1087 | } |
1184 | bzero( (caddr_t)MapP, sizeof(struct Map) ); | 1088 | bzero((caddr_t) MapP, sizeof(struct Map)); |
1185 | if (! p->RIONoMessage) | 1089 | if (!p->RIONoMessage) |
1186 | cprintf("An orphaned RTA has been adopted by %s '%s' (%c).\n",MyType,MyName,MyLink+'A'); | 1090 | cprintf("An orphaned RTA has been adopted by %s '%s' (%c).\n", MyType, MyName, MyLink + 'A'); |
1187 | } | 1091 | } else if (!p->RIONoMessage) |
1188 | else if (! p->RIONoMessage) | 1092 | cprintf("RTA connected to %s '%s' (%c) not configured.\n", MyType, MyName, MyLink + 'A'); |
1189 | cprintf("RTA connected to %s '%s' (%c) not configured.\n",MyType,MyName,MyLink+'A'); | 1093 | RIOSetChange(p); |
1190 | RIOSetChange(p); | 1094 | return TRUE; |
1191 | return TRUE; | ||
1192 | } | 1095 | } |
1193 | 1096 | ||
1194 | /* | 1097 | /* |
1195 | ** There is no room in the driver table to make an entry for the | 1098 | ** There is no room in the driver table to make an entry for the |
1196 | ** booted RTA. Keep a note of its Uniq Num in the overflow table, | 1099 | ** booted RTA. Keep a note of its Uniq Num in the overflow table, |
1197 | ** so we can ignore it's ID requests. | 1100 | ** so we can ignore it's ID requests. |
1198 | */ | 1101 | */ |
1199 | if (! p->RIONoMessage) | 1102 | if (!p->RIONoMessage) |
1200 | cprintf("The RTA connected to %s '%s' (%c) cannot be configured. You cannot configure more than 128 ports to one host card.\n",MyType,MyName,MyLink+'A'); | 1103 | cprintf("The RTA connected to %s '%s' (%c) cannot be configured. You cannot configure more than 128 ports to one host card.\n", MyType, MyName, MyLink + 'A'); |
1201 | for ( entry=0; entry<HostP->NumExtraBooted; entry++ ) | 1104 | for (entry = 0; entry < HostP->NumExtraBooted; entry++) { |
1202 | { | 1105 | if (HostP->ExtraUnits[entry] == RtaUniq) { |
1203 | if ( HostP->ExtraUnits[entry] == RtaUniq ) | 1106 | /* |
1204 | { | 1107 | ** already got it! |
1205 | /* | 1108 | */ |
1206 | ** already got it! | 1109 | return TRUE; |
1207 | */ | 1110 | } |
1208 | return TRUE; | ||
1209 | } | ||
1210 | } | 1111 | } |
1211 | /* | 1112 | /* |
1212 | ** If there is room, add the unit to the list of extras | 1113 | ** If there is room, add the unit to the list of extras |
1213 | */ | 1114 | */ |
1214 | if ( HostP->NumExtraBooted < MAX_EXTRA_UNITS ) | 1115 | if (HostP->NumExtraBooted < MAX_EXTRA_UNITS) |
1215 | HostP->ExtraUnits[HostP->NumExtraBooted++] = RtaUniq; | 1116 | HostP->ExtraUnits[HostP->NumExtraBooted++] = RtaUniq; |
1216 | return TRUE; | 1117 | return TRUE; |
1217 | } | 1118 | } |
1218 | 1119 | ||
@@ -1226,25 +1127,20 @@ static int RIOBootComplete( struct rio_info *p, struct Host *HostP, uint Rup, st | |||
1226 | ** We no longer support the RIOBootMode variable. It is all done from the | 1127 | ** We no longer support the RIOBootMode variable. It is all done from the |
1227 | ** "boot/noboot" field in the rio.cf file. | 1128 | ** "boot/noboot" field in the rio.cf file. |
1228 | */ | 1129 | */ |
1229 | int | 1130 | int RIOBootOk(p, HostP, RtaUniq) |
1230 | RIOBootOk(p, HostP, RtaUniq) | 1131 | struct rio_info *p; |
1231 | struct rio_info * p; | 1132 | struct Host *HostP; |
1232 | struct Host * HostP; | ||
1233 | ulong RtaUniq; | 1133 | ulong RtaUniq; |
1234 | { | 1134 | { |
1235 | int Entry; | 1135 | int Entry; |
1236 | uint HostUniq = HostP->UniqueNum; | 1136 | uint HostUniq = HostP->UniqueNum; |
1237 | 1137 | ||
1238 | /* | 1138 | /* |
1239 | ** Search bindings table for RTA or its parent. | 1139 | ** Search bindings table for RTA or its parent. |
1240 | ** If it exists, return 0, else 1. | 1140 | ** If it exists, return 0, else 1. |
1241 | */ | 1141 | */ |
1242 | for (Entry = 0; | 1142 | for (Entry = 0; (Entry < MAX_RTA_BINDINGS) && (p->RIOBindTab[Entry] != 0); Entry++) { |
1243 | ( Entry < MAX_RTA_BINDINGS ) && ( p->RIOBindTab[Entry] != 0 ); | 1143 | if ((p->RIOBindTab[Entry] == HostUniq) || (p->RIOBindTab[Entry] == RtaUniq)) |
1244 | Entry++) | ||
1245 | { | ||
1246 | if ( (p->RIOBindTab[Entry] == HostUniq) || | ||
1247 | (p->RIOBindTab[Entry] == RtaUniq) ) | ||
1248 | return 0; | 1144 | return 0; |
1249 | } | 1145 | } |
1250 | return 1; | 1146 | return 1; |
@@ -1255,16 +1151,15 @@ ulong RtaUniq; | |||
1255 | ** slots tentative, and the second one RTA_SECOND_SLOT as well. | 1151 | ** slots tentative, and the second one RTA_SECOND_SLOT as well. |
1256 | */ | 1152 | */ |
1257 | 1153 | ||
1258 | void | 1154 | void FillSlot(entry, entry2, RtaUniq, HostP) |
1259 | FillSlot(entry, entry2, RtaUniq, HostP) | ||
1260 | int entry; | 1155 | int entry; |
1261 | int entry2; | 1156 | int entry2; |
1262 | uint RtaUniq; | 1157 | uint RtaUniq; |
1263 | struct Host *HostP; | 1158 | struct Host *HostP; |
1264 | { | 1159 | { |
1265 | int link; | 1160 | int link; |
1266 | 1161 | ||
1267 | rio_dprintk (RIO_DEBUG_BOOT, "FillSlot(%d, %d, 0x%x...)\n", entry, entry2, RtaUniq); | 1162 | rio_dprintk(RIO_DEBUG_BOOT, "FillSlot(%d, %d, 0x%x...)\n", entry, entry2, RtaUniq); |
1268 | 1163 | ||
1269 | HostP->Mapping[entry].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE); | 1164 | HostP->Mapping[entry].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE); |
1270 | HostP->Mapping[entry].SysPort = NO_PORT; | 1165 | HostP->Mapping[entry].SysPort = NO_PORT; |
@@ -1273,8 +1168,7 @@ struct Host *HostP; | |||
1273 | HostP->Mapping[entry].ID = entry + 1; | 1168 | HostP->Mapping[entry].ID = entry + 1; |
1274 | HostP->Mapping[entry].ID2 = 0; | 1169 | HostP->Mapping[entry].ID2 = 0; |
1275 | if (entry2) { | 1170 | if (entry2) { |
1276 | HostP->Mapping[entry2].Flags = (RTA_BOOTED | RTA_NEWBOOT | | 1171 | HostP->Mapping[entry2].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE | RTA16_SECOND_SLOT); |
1277 | SLOT_TENTATIVE | RTA16_SECOND_SLOT); | ||
1278 | HostP->Mapping[entry2].SysPort = NO_PORT; | 1172 | HostP->Mapping[entry2].SysPort = NO_PORT; |
1279 | HostP->Mapping[entry2].RtaUniqueNum = RtaUniq; | 1173 | HostP->Mapping[entry2].RtaUniqueNum = RtaUniq; |
1280 | HostP->Mapping[entry2].HostUniqueNum = HostP->UniqueNum; | 1174 | HostP->Mapping[entry2].HostUniqueNum = HostP->UniqueNum; |
@@ -1284,10 +1178,10 @@ struct Host *HostP; | |||
1284 | HostP->Mapping[entry].ID2 = entry2 + 1; | 1178 | HostP->Mapping[entry].ID2 = entry2 + 1; |
1285 | } | 1179 | } |
1286 | /* | 1180 | /* |
1287 | ** Must set these up, so that utilities show | 1181 | ** Must set these up, so that utilities show |
1288 | ** topology of 16 port RTAs correctly | 1182 | ** topology of 16 port RTAs correctly |
1289 | */ | 1183 | */ |
1290 | for ( link=0; link<LINKS_PER_UNIT; link++ ) { | 1184 | for (link = 0; link < LINKS_PER_UNIT; link++) { |
1291 | HostP->Mapping[entry].Topology[link].Unit = ROUTE_DISCONNECT; | 1185 | HostP->Mapping[entry].Topology[link].Unit = ROUTE_DISCONNECT; |
1292 | HostP->Mapping[entry].Topology[link].Link = NO_LINK; | 1186 | HostP->Mapping[entry].Topology[link].Link = NO_LINK; |
1293 | if (entry2) { | 1187 | if (entry2) { |
@@ -1296,4 +1190,3 @@ struct Host *HostP; | |||
1296 | } | 1190 | } |
1297 | } | 1191 | } |
1298 | } | 1192 | } |
1299 | |||