pre-2.3.4..
[davej-history.git] / arch / ppc / kernel / residual.c
blobd9fb239702548c92681caca413393d2f8b5aa387
1 /*
2 * $Id: residual.c,v 1.15 1999/05/14 07:24:27 davem Exp $
4 * Code to deal with the PReP residual data.
6 * Written by: Cort Dougan (cort@cs.nmt.edu)
7 * Improved _greatly_ and rewritten by Gabriel Paubert (paubert@iram.es)
9 * This file is based on the following documentation:
11 * IBM Power Personal Systems Architecture
12 * Residual Data
13 * Document Number: PPS-AR-FW0001
15 * This file is subject to the terms and conditions of the GNU General Public
16 * License. See the file COPYING in the main directory of this archive
17 * for more details.
21 #include <linux/string.h>
22 #include <asm/residual.h>
23 #include <asm/pnp.h>
24 #include <asm/byteorder.h>
26 #include <linux/errno.h>
27 #include <linux/sched.h>
28 #include <linux/kernel.h>
29 #include <linux/mm.h>
30 #include <linux/stddef.h>
31 #include <linux/unistd.h>
32 #include <linux/ptrace.h>
33 #include <linux/malloc.h>
34 #include <linux/user.h>
35 #include <linux/a.out.h>
36 #include <linux/tty.h>
37 #include <linux/major.h>
38 #include <linux/interrupt.h>
39 #include <linux/reboot.h>
40 #include <linux/init.h>
41 #include <linux/blk.h>
42 #include <linux/ioport.h>
43 #include <linux/pci.h>
45 #include <asm/mmu.h>
46 #include <asm/processor.h>
47 #include <asm/io.h>
48 #include <asm/pgtable.h>
49 #include <linux/ide.h>
50 #include <asm/ide.h>
53 const char * PnP_BASE_TYPES[] __initdata = {
54 "Reserved",
55 "MassStorageDevice",
56 "NetworkInterfaceController",
57 "DisplayController",
58 "MultimediaController",
59 "MemoryController",
60 "BridgeController",
61 "CommunicationsDevice",
62 "SystemPeripheral",
63 "InputDevice",
64 "ServiceProcessor"
67 /* Device Sub Type Codes */
69 const unsigned char * PnP_SUB_TYPES[] __initdata = {
70 "\001\000SCSIController",
71 "\001\001IDEController",
72 "\001\002FloppyController",
73 "\001\003IPIController",
74 "\001\200OtherMassStorageController",
75 "\002\000EthernetController",
76 "\002\001TokenRingController",
77 "\002\002FDDIController",
78 "\002\0x80OtherNetworkController",
79 "\003\000VGAController",
80 "\003\001SVGAController",
81 "\003\002XGAController",
82 "\003\200OtherDisplayController",
83 "\004\000VideoController",
84 "\004\001AudioController",
85 "\004\200OtherMultimediaController",
86 "\005\000RAM",
87 "\005\001FLASH",
88 "\005\200OtherMemoryDevice",
89 "\006\000HostProcessorBridge",
90 "\006\001ISABridge",
91 "\006\002EISABridge",
92 "\006\003MicroChannelBridge",
93 "\006\004PCIBridge",
94 "\006\005PCMCIABridge",
95 "\006\006VMEBridge",
96 "\006\200OtherBridgeDevice",
97 "\007\000RS232Device",
98 "\007\001ATCompatibleParallelPort",
99 "\007\200OtherCommunicationsDevice",
100 "\010\000ProgrammableInterruptController",
101 "\010\001DMAController",
102 "\010\002SystemTimer",
103 "\010\003RealTimeClock",
104 "\010\004L2Cache",
105 "\010\005NVRAM",
106 "\010\006PowerManagement",
107 "\010\007CMOS",
108 "\010\010OperatorPanel",
109 "\010\011ServiceProcessorClass1",
110 "\010\012ServiceProcessorClass2",
111 "\010\013ServiceProcessorClass3",
112 "\010\014GraphicAssist",
113 "\010\017SystemPlanar",
114 "\010\200OtherSystemPeripheral",
115 "\011\000KeyboardController",
116 "\011\001Digitizer",
117 "\011\002MouseController",
118 "\011\003TabletController",
119 "\011\0x80OtherInputController",
120 "\012\000GeneralMemoryController",
121 NULL
124 /* Device Interface Type Codes */
126 const unsigned char * PnP_INTERFACES[] __initdata = {
127 "\000\000\000General",
128 "\001\000\000GeneralSCSI",
129 "\001\001\000GeneralIDE",
130 "\001\001\001ATACompatible",
132 "\001\002\000GeneralFloppy",
133 "\001\002\001Compatible765",
134 "\001\002\002NS398_Floppy", /* NS Super I/O wired to use index
135 register at port 398 and data
136 register at port 399 */
137 "\001\002\003NS26E_Floppy", /* Ports 26E and 26F */
138 "\001\002\004NS15C_Floppy", /* Ports 15C and 15D */
139 "\001\002\005NS2E_Floppy", /* Ports 2E and 2F */
140 "\001\002\006CHRP_Floppy", /* CHRP Floppy in PR*P system */
142 "\001\003\000GeneralIPI",
144 "\002\000\000GeneralEther",
145 "\002\001\000GeneralToken",
146 "\002\002\000GeneralFDDI",
148 "\003\000\000GeneralVGA",
149 "\003\001\000GeneralSVGA",
150 "\003\002\000GeneralXGA",
152 "\004\000\000GeneralVideo",
153 "\004\001\000GeneralAudio",
154 "\004\001\001CS4232Audio", /* CS 4232 Plug 'n Play Configured */
156 "\005\000\000GeneralRAM",
157 /* This one is obviously wrong ! */
158 "\005\000\000PCIMemoryController", /* PCI Config Method */
159 "\005\000\001RS6KMemoryController", /* RS6K Config Method */
160 "\005\001\000GeneralFLASH",
162 "\006\000\000GeneralHostBridge",
163 "\006\001\000GeneralISABridge",
164 "\006\002\000GeneralEISABridge",
165 "\006\003\000GeneralMCABridge",
166 /* GeneralPCIBridge = 0, */
167 "\006\004\000PCIBridgeDirect",
168 "\006\004\001PCIBridgeIndirect",
169 "\006\004\002PCIBridgeRS6K",
170 "\006\005\000GeneralPCMCIABridge",
171 "\006\006\000GeneralVMEBridge",
173 "\007\000\000GeneralRS232",
174 "\007\000\001COMx",
175 "\007\000\002Compatible16450",
176 "\007\000\003Compatible16550",
177 "\007\000\004NS398SerPort", /* NS Super I/O wired to use index
178 register at port 398 and data
179 register at port 399 */
180 "\007\000\005NS26ESerPort", /* Ports 26E and 26F */
181 "\007\000\006NS15CSerPort", /* Ports 15C and 15D */
182 "\007\000\007NS2ESerPort", /* Ports 2E and 2F */
184 "\007\001\000GeneralParPort",
185 "\007\001\001LPTx",
186 "\007\001\002NS398ParPort", /* NS Super I/O wired to use index
187 register at port 398 and data
188 register at port 399 */
189 "\007\001\003NS26EParPort", /* Ports 26E and 26F */
190 "\007\001\004NS15CParPort", /* Ports 15C and 15D */
191 "\007\001\005NS2EParPort", /* Ports 2E and 2F */
193 "\010\000\000GeneralPIC",
194 "\010\000\001ISA_PIC",
195 "\010\000\002EISA_PIC",
196 "\010\000\003MPIC",
197 "\010\000\004RS6K_PIC",
199 "\010\001\000GeneralDMA",
200 "\010\001\001ISA_DMA",
201 "\010\001\002EISA_DMA",
203 "\010\002\000GeneralTimer",
204 "\010\002\001ISA_Timer",
205 "\010\002\002EISA_Timer",
206 "\010\003\000GeneralRTC",
207 "\010\003\001ISA_RTC",
209 "\010\004\001StoreThruOnly",
210 "\010\004\002StoreInEnabled",
211 "\010\004\003RS6KL2Cache",
213 "\010\005\000IndirectNVRAM", /* Indirectly addressed */
214 "\010\005\001DirectNVRAM", /* Memory Mapped */
215 "\010\005\002IndirectNVRAM24", /* Indirectly addressed - 24 bit */
217 "\010\006\000GeneralPowerManagement",
218 "\010\006\001EPOWPowerManagement",
219 "\010\006\002PowerControl", // d1378
221 "\010\007\000GeneralCMOS",
223 "\010\010\000GeneralOPPanel",
224 "\010\010\001HarddiskLight",
225 "\010\010\002CDROMLight",
226 "\010\010\003PowerLight",
227 "\010\010\004KeyLock",
228 "\010\010\005ANDisplay", /* AlphaNumeric Display */
229 "\010\010\006SystemStatusLED", /* 3 digit 7 segment LED */
230 "\010\010\007CHRP_SystemStatusLED", /* CHRP LEDs in PR*P system */
232 "\010\011\000GeneralServiceProcessor",
233 "\010\012\000GeneralServiceProcessor",
234 "\010\013\000GeneralServiceProcessor",
236 "\010\014\001TransferData",
237 "\010\014\002IGMC32",
238 "\010\014\003IGMC64",
240 "\010\017\000GeneralSystemPlanar", /* 10/5/95 */
241 NULL
244 static const unsigned char __init *PnP_SUB_TYPE_STR(unsigned char BaseType,
245 unsigned char SubType) {
246 const unsigned char ** s=PnP_SUB_TYPES;
247 while (*s && !((*s)[0]==BaseType
248 && (*s)[1]==SubType)) s++;
249 if (*s) return *s+2;
250 else return("Unknown !");
253 static const unsigned char __init *PnP_INTERFACE_STR(unsigned char BaseType,
254 unsigned char SubType,
255 unsigned char Interface) {
256 const unsigned char ** s=PnP_INTERFACES;
257 while (*s && !((*s)[0]==BaseType
258 && (*s)[1]==SubType
259 && (*s)[2]==Interface)) s++;
260 if (*s) return *s+3;
261 else return NULL;
264 static void __init printsmallvendor(PnP_TAG_PACKET *pkt, int size) {
265 int i, c;
266 char decomp[4];
267 #define p pkt->S14_Pack.S14_Data.S14_PPCPack
268 switch(p.Type) {
269 case 1:
270 /* Decompress first 3 chars */
271 c = *(unsigned short *)p.PPCData;
272 decomp[0]='A'-1+((c>>10)&0x1F);
273 decomp[1]='A'-1+((c>>5)&0x1F);
274 decomp[2]='A'-1+(c&0x1F);
275 decomp[3]=0;
276 printk(" Chip identification: %s%4.4X\n",
277 decomp, ld_le16((unsigned short *)(p.PPCData+2)));
278 break;
279 default:
280 printk(" Small vendor item type 0x%2.2x, data (hex): ",
281 p.Type);
282 for(i=0; i<size-2; i++) printk("%2.2x ", p.PPCData[i]);
283 printk("\n");
284 break;
286 #undef p
289 static void __init printsmallpacket(PnP_TAG_PACKET * pkt, int size) {
290 static const unsigned char * intlevel[] = {"high", "low"};
291 static const unsigned char * intsense[] = {"edge", "level"};
293 switch (tag_small_item_name(pkt->S1_Pack.Tag)) {
294 case PnPVersion:
295 printk(" PnPversion 0x%x.%x\n",
296 pkt->S1_Pack.Version[0], /* How to interpret version ? */
297 pkt->S1_Pack.Version[1]);
298 break;
299 // case Logicaldevice:
300 break;
301 // case CompatibleDevice:
302 break;
303 case IRQFormat:
304 #define p pkt->S4_Pack
305 printk(" IRQ Mask 0x%4.4x, %s %s sensitive\n",
306 ld_le16((unsigned short *)p.IRQMask),
307 intlevel[(size>3) ? !(p.IRQInfo&0x05) : 0],
308 intsense[(size>3) ? !(p.IRQInfo&0x03) : 0]);
309 #undef p
310 break;
311 case DMAFormat:
312 #define p pkt->S5_Pack
313 printk(" DMA channel mask 0x%2.2x, info 0x%2.2x\n",
314 p.DMAMask, p.DMAInfo);
315 #undef p
316 break;
317 case StartDepFunc:
318 printk("Start dependent function:\n");
319 break;
320 case EndDepFunc:
321 printk("End dependent function\n");
322 break;
323 case IOPort:
324 #define p pkt->S8_Pack
325 printk(" Variable (%d decoded bits) I/O port\n"
326 " from 0x%4.4x to 0x%4.4x, alignment %d, %d ports\n",
327 p.IOInfo&ISAAddr16bit?16:10,
328 ld_le16((unsigned short *)p.RangeMin),
329 ld_le16((unsigned short *)p.RangeMax),
330 p.IOAlign, p.IONum);
331 #undef p
332 break;
333 case FixedIOPort:
334 #define p pkt->S9_Pack
335 printk(" Fixed (10 decoded bits) I/O port from %3.3x to %3.3x\n",
336 (p.Range[1]<<8)|p.Range[0],
337 ((p.Range[1]<<8)|p.Range[0])+p.IONum-1);
338 #undef p
339 break;
340 case Res1:
341 case Res2:
342 case Res3:
343 printk(" Undefined packet type %d!\n",
344 tag_small_item_name(pkt->S1_Pack.Tag));
345 break;
346 case SmallVendorItem:
347 printsmallvendor(pkt,size);
348 break;
349 default:
350 printk(" Type 0x2.2x%d, size=%d\n",
351 pkt->S1_Pack.Tag, size);
352 break;
356 static void __init printlargevendor(PnP_TAG_PACKET * pkt, int size) {
357 static const unsigned char * addrtype[] = {"I/O", "Memory", "System"};
358 static const unsigned char * inttype[] = {"8259", "MPIC", "RS6k BUID %d"};
359 static const unsigned char * convtype[] = {"Bus Memory", "Bus I/O", "DMA"};
360 static const unsigned char * transtype[] = {"direct", "mapped", "direct-store segment"};
361 static const unsigned char * L2type[] = {"WriteThru", "CopyBack"};
362 static const unsigned char * L2assoc[] = {"DirectMapped", "2-way set"};
364 int i;
365 char tmpstr[30], *t;
366 #define p pkt->L4_Pack.L4_Data.L4_PPCPack
367 switch(p.Type) {
368 case 2:
369 printk(" %d K %s %s L2 cache, %d/%d bytes line/sector size\n",
370 ld_le32((unsigned int *)p.PPCData),
371 L2type[p.PPCData[10]-1],
372 L2assoc[p.PPCData[4]-1],
373 ld_le16((unsigned short *)p.PPCData+3),
374 ld_le16((unsigned short *)p.PPCData+4));
375 break;
376 case 3:
377 printk(" PCI Bridge parameters\n"
378 " ConfigBaseAddress %0x\n"
379 " ConfigBaseData %0x\n"
380 " Bus number %d\n",
381 ld_le32((unsigned int *)p.PPCData),
382 ld_le32((unsigned int *)(p.PPCData+8)),
383 p.PPCData[16]);
384 for(i=20; i<size-4; i+=12) {
385 int j, first;
386 if(p.PPCData[i]) printk(" PCI Slot %d", p.PPCData[i]);
387 else printk (" Integrated PCI device");
388 for(j=0, first=1, t=tmpstr; j<4; j++) {
389 int line=ld_le16((unsigned short *)(p.PPCData+i+4)+j);
390 if(line!=0xffff){
391 if(first) first=0; else *t++='/';
392 *t++='A'+j;
395 *t='\0';
396 printk(" DevFunc 0x%x interrupt line(s) %s routed to",
397 p.PPCData[i+1],tmpstr);
398 sprintf(tmpstr,
399 inttype[p.PPCData[i+2]-1],
400 p.PPCData[i+3]);
401 printk(" %s line(s) ",
402 tmpstr);
403 for(j=0, first=1, t=tmpstr; j<4; j++) {
404 int line=ld_le16((unsigned short *)(p.PPCData+i+4)+j);
405 if(line!=0xffff){
406 if(first) first=0; else *t++='/';
407 t+=sprintf(t,"%d(%c)",
408 line&0x7fff,
409 line&0x8000?'E':'L');
412 printk("%s\n",tmpstr);
414 break;
415 case 5:
416 printk(" Bridge address translation, %s decoding:\n"
417 " Processor Bus Size Conversion Translation\n"
418 " 0x%8.8x 0x%8.8x 0x%8.8x %s %s\n",
419 p.PPCData[0]&1 ? "positive" : "subtractive",
420 ld_le32((unsigned int *)p.PPCData+1),
421 ld_le32((unsigned int *)p.PPCData+3),
422 ld_le32((unsigned int *)p.PPCData+5),
423 convtype[p.PPCData[2]-1],
424 transtype[p.PPCData[1]-1]);
425 break;
426 case 6:
427 printk(" Bus speed %d Hz, %d slot(s)\n",
428 ld_le32((unsigned int *)p.PPCData),
429 p.PPCData[4]);
430 break;
431 case 7:
432 printk(" SCSI buses: %d, id(s):", p.PPCData[0]);
433 for(i=1; i<=p.PPCData[0]; i++)
434 printk(" %d%c", p.PPCData[i], i==p.PPCData[0] ? '\n' : ',');
435 break;
436 case 9:
437 printk(" %s address (%d bits), at 0x%x size 0x%x bytes\n",
438 addrtype[p.PPCData[0]-1],
439 p.PPCData[1],
440 ld_le32((unsigned int *)(p.PPCData+4)),
441 ld_le32((unsigned int *)(p.PPCData+12)));
442 break;
443 case 10:
444 sprintf(tmpstr,
445 inttype[p.PPCData[0]-1],
446 p.PPCData[1]);
448 printk(" ISA interrupts routed to %s\n"
449 " lines",
450 tmpstr);
451 for(i=0; i<16; i++) {
452 int line=ld_le16((unsigned short *)p.PPCData+i+1);
453 if (line!=0xffff) printk(" %d(IRQ%d)", line, i);
455 printk("\n");
456 break;
457 default:
458 printk(" Large vendor item type 0x%2.2x\n Data (hex):",
459 p.Type);
460 for(i=0; i<size-4; i++) printk(" %2.2x", p.PPCData[i]);
461 printk("\n");
462 #undef p
466 static void __init printlargepacket(PnP_TAG_PACKET * pkt, int size) {
467 switch (tag_large_item_name(pkt->S1_Pack.Tag)) {
468 case LargeVendorItem:
469 printlargevendor(pkt, size);
470 break;
471 default:
472 printk(" Type 0x2.2x%d, size=%d\n",
473 pkt->S1_Pack.Tag, size);
474 break;
477 static void __init printpackets(PnP_TAG_PACKET * pkt, const char * cat) {
478 if (pkt->S1_Pack.Tag== END_TAG) {
479 printk(" No packets describing %s resources.\n", cat);
480 return;
482 printk( " Packets describing %s resources:\n",cat);
483 do {
484 int size;
485 if (tag_type(pkt->S1_Pack.Tag)) {
486 size= 3 +
487 pkt->L1_Pack.Count0 +
488 pkt->L1_Pack.Count1*256;
489 printlargepacket(pkt, size);
490 } else {
491 size=tag_small_count(pkt->S1_Pack.Tag)+1;
492 printsmallpacket(pkt, size);
494 (unsigned char *) pkt+=size;
495 } while (pkt->S1_Pack.Tag != END_TAG);
498 void __init print_residual_device_info(void)
500 int i;
501 PPC_DEVICE *dev;
502 #define did dev->DeviceId
504 /* make sure we have residual data first */
505 if ( res->ResidualLength == 0 )
506 return;
508 printk("Residual: %ld devices\n", res->ActualNumDevices);
509 for ( i = 0;
510 i < res->ActualNumDevices ;
511 i++)
513 char decomp[4], sn[20];
514 const char * s;
515 dev = &res->Devices[i];
516 s = PnP_INTERFACE_STR(did.BaseType, did.SubType,
517 did.Interface);
518 if(!s) {
519 sprintf(sn, "interface %d", did.Interface);
520 s=sn;
522 if ( did.BusId & PCIDEVICE )
523 printk("PCI Device, Bus %d, DevFunc 0x%x:",
524 dev->BusAccess.PCIAccess.BusNumber,
525 dev->BusAccess.PCIAccess.DevFuncNumber);
526 if ( did.BusId & PNPISADEVICE ) printk("PNPISA Device:");
527 if ( did.BusId & ISADEVICE )
528 printk("ISA Device, Slot %d, LogicalDev %d:",
529 dev->BusAccess.ISAAccess.SlotNumber,
530 dev->BusAccess.ISAAccess.LogicalDevNumber);
531 if ( did.BusId & EISADEVICE ) printk("EISA Device:");
532 if ( did.BusId & PROCESSORDEVICE )
533 printk("ProcBus Device, Bus %d, BUID %d: ",
534 dev->BusAccess.ProcBusAccess.BusNumber,
535 dev->BusAccess.ProcBusAccess.BUID);
536 if ( did.BusId & PCMCIADEVICE ) printk("PCMCIA ");
537 if ( did.BusId & VMEDEVICE ) printk("VME ");
538 if ( did.BusId & MCADEVICE ) printk("MCA ");
539 if ( did.BusId & MXDEVICE ) printk("MX ");
540 /* Decompress first 3 chars */
541 decomp[0]='A'-1+((did.DevId>>26)&0x1F);
542 decomp[1]='A'-1+((did.DevId>>21)&0x1F);
543 decomp[2]='A'-1+((did.DevId>>16)&0x1F);
544 decomp[3]=0;
545 printk(" %s%4.4lX, %s, %s, %s\n",
546 decomp, did.DevId&0xffff,
547 PnP_BASE_TYPES[did.BaseType],
548 PnP_SUB_TYPE_STR(did.BaseType,did.SubType),
550 if ( dev->AllocatedOffset )
551 printpackets( (union _PnP_TAG_PACKET *)
552 &res->DevicePnPHeap[dev->AllocatedOffset],
553 "allocated");
554 if ( dev->PossibleOffset )
555 printpackets( (union _PnP_TAG_PACKET *)
556 &res->DevicePnPHeap[dev->PossibleOffset],
557 "possible");
558 if ( dev->CompatibleOffset )
559 printpackets( (union _PnP_TAG_PACKET *)
560 &res->DevicePnPHeap[dev->CompatibleOffset],
561 "compatible");
566 #if 0
567 static void __init printVPD(void) {
568 #define vpd res->VitalProductData
569 int ps=vpd.PageSize, i, j;
570 static const char* Usage[]={
571 "FirmwareStack", "FirmwareHeap", "FirmwareCode", "BootImage",
572 "Free", "Unpopulated", "ISAAddr", "PCIConfig",
573 "IOMemory", "SystemIO", "SystemRegs", "PCIAddr",
574 "UnPopSystemRom", "SystemROM", "ResumeBlock", "Other"
576 static const unsigned char *FWMan[]={
577 "IBM", "Motorola", "FirmWorks", "Bull"
579 static const unsigned char *FWFlags[]={
580 "Conventional", "OpenFirmware", "Diagnostics", "LowDebug",
581 "MultiBoot", "LowClient", "Hex41", "FAT",
582 "ISO9660", "SCSI_ID_Override", "Tape_Boot", "FW_Boot_Path"
584 static const unsigned char *ESM[]={
585 "Port92", "PCIConfigA8", "FF001030", "????????"
587 static const unsigned char *SIOM[]={
588 "Port850", "????????", "PCIConfigA8", "????????"
591 printk("Model: %s\n",vpd.PrintableModel);
592 printk("Serial: %s\n", vpd.Serial);
593 printk("FirmwareSupplier: %s\n", FWMan[vpd.FirmwareSupplier]);
594 printk("FirmwareFlags:");
595 for(j=0; j<12; j++) {
596 if (vpd.FirmwareSupports & (1<<j)) {
597 printk(" %s%c", FWFlags[j],
598 vpd.FirmwareSupports&(-2<<j) ? ',' : '\n');
601 printk("NVRamSize: %ld\n", vpd.NvramSize);
602 printk("SIMMslots: %ld\n", vpd.NumSIMMSlots);
603 printk("EndianSwitchMethod: %s\n",
604 ESM[vpd.EndianSwitchMethod>2 ? 2 : vpd.EndianSwitchMethod]);
605 printk("SpreadIOMethod: %s\n",
606 SIOM[vpd.SpreadIOMethod>3 ? 3 : vpd.SpreadIOMethod]);
607 printk("Processor/Bus frequencies (Hz): %ld/%ld\n",
608 vpd.ProcessorHz, vpd.ProcessorBusHz);
609 printk("Time Base Divisor: %ld\n", vpd.TimeBaseDivisor);
610 printk("WordWidth, PageSize: %ld, %d\n", vpd.WordWidth, ps);
611 printk("Cache sector size, Lock granularity: %ld, %ld\n",
612 vpd.CoherenceBlockSize, vpd.GranuleSize);
613 for (i=0; i<res->ActualNumMemSegs; i++) {
614 int mask=res->Segs[i].Usage, first, j;
615 printk("%8.8lx-%8.8lx ",
616 res->Segs[i].BasePage*ps,
617 (res->Segs[i].PageCount+res->Segs[i].BasePage)*ps-1);
618 for(j=15, first=1; j>=0; j--) {
619 if (mask&(1<<j)) {
620 if (first) first=0;
621 else printk(", ");
622 printk("%s", Usage[j]);
625 printk("\n");
630 * Spit out some info about residual data
632 void print_residual_device_info(void)
634 int i;
635 union _PnP_TAG_PACKET *pkt;
636 PPC_DEVICE *dev;
637 #define did dev->DeviceId
639 /* make sure we have residual data first */
640 if ( res->ResidualLength == 0 )
641 return;
642 printk("Residual: %ld devices\n", res->ActualNumDevices);
643 for ( i = 0;
644 i < res->ActualNumDevices ;
645 i++)
647 dev = &res->Devices[i];
649 * pci devices
651 if ( did.BusId & PCIDEVICE )
653 printk("PCI Device:");
654 /* unknown vendor */
655 if ( !strncmp( "Unknown", pci_strvendor(did.DevId>>16), 7) )
656 printk(" id %08lx types %d/%d", did.DevId,
657 did.BaseType, did.SubType);
658 /* known vendor */
659 else
660 printk(" %s %s",
661 pci_strvendor(did.DevId>>16),
662 pci_strdev(did.DevId>>16,
663 did.DevId&0xffff)
666 if ( did.BusId & PNPISADEVICE )
668 printk(" pnp:");
669 /* get pnp info on the device */
670 pkt = (union _PnP_TAG_PACKET *)
671 &res->DevicePnPHeap[dev->AllocatedOffset];
672 for (; pkt->S1_Pack.Tag != DF_END_TAG;
673 pkt++ )
675 if ( (pkt->S1_Pack.Tag == S4_Packet) ||
676 (pkt->S1_Pack.Tag == S4_Packet_flags) )
677 printk(" irq %02x%02x",
678 pkt->S4_Pack.IRQMask[0],
679 pkt->S4_Pack.IRQMask[1]);
682 printk("\n");
683 continue;
686 * isa devices
688 if ( did.BusId & ISADEVICE )
690 printk("ISA Device: basetype: %d subtype: %d",
691 did.BaseType, did.SubType);
692 printk("\n");
693 continue;
696 * eisa devices
698 if ( did.BusId & EISADEVICE )
700 printk("EISA Device: basetype: %d subtype: %d",
701 did.BaseType, did.SubType);
702 printk("\n");
703 continue;
706 * proc bus devices
708 if ( did.BusId & PROCESSORDEVICE )
710 printk("ProcBus Device: basetype: %d subtype: %d",
711 did.BaseType, did.SubType);
712 printk("\n");
713 continue;
716 * pcmcia devices
718 if ( did.BusId & PCMCIADEVICE )
720 printk("PCMCIA Device: basetype: %d subtype: %d",
721 did.BaseType, did.SubType);
722 printk("\n");
723 continue;
725 printk("Unknown bus access device: busid %lx\n",
726 did.BusId);
729 #endif
731 /* Returns the device index in the residual data,
732 any of the search items may be set as -1 for wildcard,
733 DevID number field (second halfword) is big endian !
735 Examples:
736 - search for the Interrupt controller (8259 type), 2 methods:
737 1) i8259 = residual_find_device(~0,
738 NULL,
739 SystemPeripheral,
740 ProgrammableInterruptController,
741 ISA_PIC,
743 2) i8259 = residual_find_device(~0, "PNP0000", -1, -1, -1, 0)
745 - search for the first two serial devices, whatever their type)
746 iserial1 = residual_find_device(~0,NULL,
747 CommunicationsDevice,
748 RS232Device,
749 -1, 0)
750 iserial2 = residual_find_device(~0,NULL,
751 CommunicationsDevice,
752 RS232Device,
753 -1, 1)
754 - but search for typical COM1 and COM2 is not easy due to the
755 fact that the interface may be anything and the name "PNP0500" or
756 "PNP0501". Quite bad.
760 /* devid are easier to uncompress than to compress, so to minimize bloat
761 in this rarely used area we unencode and compare */
763 /* in residual data number is big endian in the device table and
764 little endian in the heap, so we use two parameters to avoid writing
765 two very similar functions */
767 static int __init same_DevID(unsigned short vendor,
768 unsigned short Number,
769 char * str)
771 static unsigned const char hexdigit[]="0123456789ABCDEF";
772 if (strlen(str)!=7) return 0;
773 if ( ( ((vendor>>10)&0x1f)+'A'-1 == str[0]) &&
774 ( ((vendor>>5)&0x1f)+'A'-1 == str[1]) &&
775 ( (vendor&0x1f)+'A'-1 == str[2]) &&
776 (hexdigit[(Number>>12)&0x0f] == str[3]) &&
777 (hexdigit[(Number>>8)&0x0f] == str[4]) &&
778 (hexdigit[(Number>>4)&0x0f] == str[5]) &&
779 (hexdigit[Number&0x0f] == str[6]) ) return 1;
780 return 0;
783 PPC_DEVICE __init *residual_find_device(unsigned long BusMask,
784 unsigned char * DevID,
785 int BaseType,
786 int SubType,
787 int Interface,
788 int n)
790 int i;
791 if ( !res->ResidualLength ) return NULL;
792 for (i=0; i<res->ActualNumDevices; i++) {
793 #define Dev res->Devices[i].DeviceId
794 if ( (Dev.BusId&BusMask) &&
795 (BaseType==-1 || Dev.BaseType==BaseType) &&
796 (SubType==-1 || Dev.SubType==SubType) &&
797 (Interface==-1 || Dev.Interface==Interface) &&
798 (DevID==NULL || same_DevID((Dev.DevId>>16)&0xffff,
799 Dev.DevId&0xffff, DevID)) &&
800 !(n--) ) return res->Devices+i;
801 #undef Dev
803 return 0;
806 PPC_DEVICE __init *residual_find_device_id(unsigned long BusMask,
807 unsigned short DevID,
808 int BaseType,
809 int SubType,
810 int Interface,
811 int n)
813 int i;
814 if ( !res->ResidualLength ) return NULL;
815 for (i=0; i<res->ActualNumDevices; i++) {
816 #define Dev res->Devices[i].DeviceId
817 if ( (Dev.BusId&BusMask) &&
818 (BaseType==-1 || Dev.BaseType==BaseType) &&
819 (SubType==-1 || Dev.SubType==SubType) &&
820 (Interface==-1 || Dev.Interface==Interface) &&
821 (DevID==0xffff || (Dev.DevId&0xffff) == DevID) &&
822 !(n--) ) return res->Devices+i;
823 #undef Dev
825 return 0;
828 PnP_TAG_PACKET *PnP_find_packet(unsigned char *p,
829 unsigned packet_tag,
830 int n)
832 unsigned mask, masked_tag, size;
833 if(!p) return 0;
834 if (tag_type(packet_tag)) mask=0xff; else mask=0xF8;
835 masked_tag = packet_tag&mask;
836 for(; *p != END_TAG; p+=size) {
837 if ((*p & mask) == masked_tag && !(n--))
838 return (PnP_TAG_PACKET *) p;
839 if (tag_type(*p))
840 size=ld_le16((unsigned short *)(p+1))+3;
841 else
842 size=tag_small_count(*p)+1;
844 return 0; /* not found */
847 PnP_TAG_PACKET __init *PnP_find_small_vendor_packet(unsigned char *p,
848 unsigned packet_type,
849 int n)
851 int next=0;
852 while (p) {
853 p = (unsigned char *) PnP_find_packet(p, 0x70, next);
854 if (p && p[1]==packet_type && !(n--))
855 return (PnP_TAG_PACKET *) p;
856 next = 1;
858 return 0; /* not found */
861 PnP_TAG_PACKET __init *PnP_find_large_vendor_packet(unsigned char *p,
862 unsigned packet_type,
863 int n)
865 int next=0;
866 while (p) {
867 p = (unsigned char *) PnP_find_packet(p, 0x84, next);
868 if (p && p[3]==packet_type && !(n--))
869 return (PnP_TAG_PACKET *) p;
870 next = 1;
872 return 0; /* not found */