1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <linux/string.h>
20#include <asm/residual.h>
21#include <asm/pnp.h>
22#include <asm/byteorder.h>
23
24#include <linux/errno.h>
25#include <linux/sched.h>
26#include <linux/kernel.h>
27#include <linux/mm.h>
28#include <linux/stddef.h>
29#include <linux/unistd.h>
30#include <linux/ptrace.h>
31#include <linux/slab.h>
32#include <linux/user.h>
33#include <linux/a.out.h>
34#include <linux/tty.h>
35#include <linux/major.h>
36#include <linux/interrupt.h>
37#include <linux/reboot.h>
38#include <linux/init.h>
39#include <linux/ioport.h>
40#include <linux/pci.h>
41#include <linux/ide.h>
42
43#include <asm/sections.h>
44#include <asm/mmu.h>
45#include <asm/io.h>
46#include <asm/pgtable.h>
47#include <asm/ide.h>
48
49
50unsigned char __res[sizeof(RESIDUAL)] = {0,};
51RESIDUAL *res = (RESIDUAL *)&__res;
52
53char * 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"
65 };
66
67
68
69unsigned 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
122};
123
124
125
126unsigned char * PnP_INTERFACES[] __initdata = {
127 "\000\000\000General",
128 "\001\000\000GeneralSCSI",
129 "\001\001\000GeneralIDE",
130 "\001\001\001ATACompatible",
131
132 "\001\002\000GeneralFloppy",
133 "\001\002\001Compatible765",
134 "\001\002\002NS398_Floppy",
135
136
137 "\001\002\003NS26E_Floppy",
138 "\001\002\004NS15C_Floppy",
139 "\001\002\005NS2E_Floppy",
140 "\001\002\006CHRP_Floppy",
141
142 "\001\003\000GeneralIPI",
143
144 "\002\000\000GeneralEther",
145 "\002\001\000GeneralToken",
146 "\002\002\000GeneralFDDI",
147
148 "\003\000\000GeneralVGA",
149 "\003\001\000GeneralSVGA",
150 "\003\002\000GeneralXGA",
151
152 "\004\000\000GeneralVideo",
153 "\004\001\000GeneralAudio",
154 "\004\001\001CS4232Audio",
155
156 "\005\000\000GeneralRAM",
157
158 "\005\000\000PCIMemoryController",
159 "\005\000\001RS6KMemoryController",
160 "\005\001\000GeneralFLASH",
161
162 "\006\000\000GeneralHostBridge",
163 "\006\001\000GeneralISABridge",
164 "\006\002\000GeneralEISABridge",
165 "\006\003\000GeneralMCABridge",
166
167 "\006\004\000PCIBridgeDirect",
168 "\006\004\001PCIBridgeIndirect",
169 "\006\004\002PCIBridgeRS6K",
170 "\006\005\000GeneralPCMCIABridge",
171 "\006\006\000GeneralVMEBridge",
172
173 "\007\000\000GeneralRS232",
174 "\007\000\001COMx",
175 "\007\000\002Compatible16450",
176 "\007\000\003Compatible16550",
177 "\007\000\004NS398SerPort",
178
179
180 "\007\000\005NS26ESerPort",
181 "\007\000\006NS15CSerPort",
182 "\007\000\007NS2ESerPort",
183
184 "\007\001\000GeneralParPort",
185 "\007\001\001LPTx",
186 "\007\001\002NS398ParPort",
187
188
189 "\007\001\003NS26EParPort",
190 "\007\001\004NS15CParPort",
191 "\007\001\005NS2EParPort",
192
193 "\010\000\000GeneralPIC",
194 "\010\000\001ISA_PIC",
195 "\010\000\002EISA_PIC",
196 "\010\000\003MPIC",
197 "\010\000\004RS6K_PIC",
198
199 "\010\001\000GeneralDMA",
200 "\010\001\001ISA_DMA",
201 "\010\001\002EISA_DMA",
202
203 "\010\002\000GeneralTimer",
204 "\010\002\001ISA_Timer",
205 "\010\002\002EISA_Timer",
206 "\010\003\000GeneralRTC",
207 "\010\003\001ISA_RTC",
208
209 "\010\004\001StoreThruOnly",
210 "\010\004\002StoreInEnabled",
211 "\010\004\003RS6KL2Cache",
212
213 "\010\005\000IndirectNVRAM",
214 "\010\005\001DirectNVRAM",
215 "\010\005\002IndirectNVRAM24",
216
217 "\010\006\000GeneralPowerManagement",
218 "\010\006\001EPOWPowerManagement",
219 "\010\006\002PowerControl",
220
221 "\010\007\000GeneralCMOS",
222
223 "\010\010\000GeneralOPPanel",
224 "\010\010\001HarddiskLight",
225 "\010\010\002CDROMLight",
226 "\010\010\003PowerLight",
227 "\010\010\004KeyLock",
228 "\010\010\005ANDisplay",
229 "\010\010\006SystemStatusLED",
230 "\010\010\007CHRP_SystemStatusLED",
231
232 "\010\011\000GeneralServiceProcessor",
233 "\010\012\000GeneralServiceProcessor",
234 "\010\013\000GeneralServiceProcessor",
235
236 "\010\014\001TransferData",
237 "\010\014\002IGMC32",
238 "\010\014\003IGMC64",
239
240 "\010\017\000GeneralSystemPlanar",
241 NULL
242 };
243
244static const unsigned char __init *PnP_SUB_TYPE_STR(unsigned char BaseType,
245 unsigned char SubType) {
246 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 !");
251};
252
253static const unsigned char __init *PnP_INTERFACE_STR(unsigned char BaseType,
254 unsigned char SubType,
255 unsigned char Interface) {
256 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;
262};
263
264static 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
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;
285 }
286#undef p
287}
288
289static 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"};
292
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],
297 pkt->S1_Pack.Version[1]);
298 break;
299
300 break;
301
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;
353 }
354}
355
356static 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"};
363
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;
393 }
394 }
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');
410 }
411 }
412 printk("%s\n",tmpstr);
413 }
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]);
447
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);
454 }
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
463 }
464}
465
466static 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;
475 }
476}
477
478static void __init printpackets(PnP_TAG_PACKET * pkt, const char * cat)
479{
480 if (pkt->S1_Pack.Tag== END_TAG) {
481 printk(" No packets describing %s resources.\n", cat);
482 return;
483 }
484 printk( " Packets describing %s resources:\n",cat);
485 do {
486 int size;
487 if (tag_type(pkt->S1_Pack.Tag)) {
488 size= 3 +
489 pkt->L1_Pack.Count0 +
490 pkt->L1_Pack.Count1*256;
491 printlargepacket(pkt, size);
492 } else {
493 size=tag_small_count(pkt->S1_Pack.Tag)+1;
494 printsmallpacket(pkt, size);
495 }
496 pkt = (PnP_TAG_PACKET *)((unsigned char *) pkt + size);
497 } while (pkt->S1_Pack.Tag != END_TAG);
498}
499
500void __init print_residual_device_info(void)
501{
502 int i;
503 PPC_DEVICE *dev;
504#define did dev->DeviceId
505
506
507 if (!have_residual_data)
508 return;
509
510 printk("Residual: %ld devices\n", res->ActualNumDevices);
511 for ( i = 0;
512 i < res->ActualNumDevices ;
513 i++)
514 {
515 char decomp[4], sn[20];
516 const char * s;
517 dev = &res->Devices[i];
518 s = PnP_INTERFACE_STR(did.BaseType, did.SubType,
519 did.Interface);
520 if(!s) {
521 sprintf(sn, "interface %d", did.Interface);
522 s=sn;
523 }
524 if ( did.BusId & PCIDEVICE )
525 printk("PCI Device, Bus %d, DevFunc 0x%x:",
526 dev->BusAccess.PCIAccess.BusNumber,
527 dev->BusAccess.PCIAccess.DevFuncNumber);
528 if ( did.BusId & PNPISADEVICE ) printk("PNPISA Device:");
529 if ( did.BusId & ISADEVICE )
530 printk("ISA Device, Slot %d, LogicalDev %d:",
531 dev->BusAccess.ISAAccess.SlotNumber,
532 dev->BusAccess.ISAAccess.LogicalDevNumber);
533 if ( did.BusId & EISADEVICE ) printk("EISA Device:");
534 if ( did.BusId & PROCESSORDEVICE )
535 printk("ProcBus Device, Bus %d, BUID %d: ",
536 dev->BusAccess.ProcBusAccess.BusNumber,
537 dev->BusAccess.ProcBusAccess.BUID);
538 if ( did.BusId & PCMCIADEVICE ) printk("PCMCIA ");
539 if ( did.BusId & VMEDEVICE ) printk("VME ");
540 if ( did.BusId & MCADEVICE ) printk("MCA ");
541 if ( did.BusId & MXDEVICE ) printk("MX ");
542
543 decomp[0]='A'-1+((did.DevId>>26)&0x1F);
544 decomp[1]='A'-1+((did.DevId>>21)&0x1F);
545 decomp[2]='A'-1+((did.DevId>>16)&0x1F);
546 decomp[3]=0;
547 printk(" %s%4.4lX, %s, %s, %s\n",
548 decomp, did.DevId&0xffff,
549 PnP_BASE_TYPES[did.BaseType],
550 PnP_SUB_TYPE_STR(did.BaseType,did.SubType),
551 s);
552 if ( dev->AllocatedOffset )
553 printpackets( (union _PnP_TAG_PACKET *)
554 &res->DevicePnPHeap[dev->AllocatedOffset],
555 "allocated");
556 if ( dev->PossibleOffset )
557 printpackets( (union _PnP_TAG_PACKET *)
558 &res->DevicePnPHeap[dev->PossibleOffset],
559 "possible");
560 if ( dev->CompatibleOffset )
561 printpackets( (union _PnP_TAG_PACKET *)
562 &res->DevicePnPHeap[dev->CompatibleOffset],
563 "compatible");
564 }
565}
566
567
568#if 0
569static void __init printVPD(void) {
570#define vpd res->VitalProductData
571 int ps=vpd.PageSize, i, j;
572 static const char* Usage[]={
573 "FirmwareStack", "FirmwareHeap", "FirmwareCode", "BootImage",
574 "Free", "Unpopulated", "ISAAddr", "PCIConfig",
575 "IOMemory", "SystemIO", "SystemRegs", "PCIAddr",
576 "UnPopSystemRom", "SystemROM", "ResumeBlock", "Other"
577 };
578 static const unsigned char *FWMan[]={
579 "IBM", "Motorola", "FirmWorks", "Bull"
580 };
581 static const unsigned char *FWFlags[]={
582 "Conventional", "OpenFirmware", "Diagnostics", "LowDebug",
583 "MultiBoot", "LowClient", "Hex41", "FAT",
584 "ISO9660", "SCSI_ID_Override", "Tape_Boot", "FW_Boot_Path"
585 };
586 static const unsigned char *ESM[]={
587 "Port92", "PCIConfigA8", "FF001030", "????????"
588 };
589 static const unsigned char *SIOM[]={
590 "Port850", "????????", "PCIConfigA8", "????????"
591 };
592
593 printk("Model: %s\n",vpd.PrintableModel);
594 printk("Serial: %s\n", vpd.Serial);
595 printk("FirmwareSupplier: %s\n", FWMan[vpd.FirmwareSupplier]);
596 printk("FirmwareFlags:");
597 for(j=0; j<12; j++) {
598 if (vpd.FirmwareSupports & (1<<j)) {
599 printk(" %s%c", FWFlags[j],
600 vpd.FirmwareSupports&(-2<<j) ? ',' : '\n');
601 }
602 }
603 printk("NVRamSize: %ld\n", vpd.NvramSize);
604 printk("SIMMslots: %ld\n", vpd.NumSIMMSlots);
605 printk("EndianSwitchMethod: %s\n",
606 ESM[vpd.EndianSwitchMethod>2 ? 2 : vpd.EndianSwitchMethod]);
607 printk("SpreadIOMethod: %s\n",
608 SIOM[vpd.SpreadIOMethod>3 ? 3 : vpd.SpreadIOMethod]);
609 printk("Processor/Bus frequencies (Hz): %ld/%ld\n",
610 vpd.ProcessorHz, vpd.ProcessorBusHz);
611 printk("Time Base Divisor: %ld\n", vpd.TimeBaseDivisor);
612 printk("WordWidth, PageSize: %ld, %d\n", vpd.WordWidth, ps);
613 printk("Cache sector size, Lock granularity: %ld, %ld\n",
614 vpd.CoherenceBlockSize, vpd.GranuleSize);
615 for (i=0; i<res->ActualNumMemSegs; i++) {
616 int mask=res->Segs[i].Usage, first, j;
617 printk("%8.8lx-%8.8lx ",
618 res->Segs[i].BasePage*ps,
619 (res->Segs[i].PageCount+res->Segs[i].BasePage)*ps-1);
620 for(j=15, first=1; j>=0; j--) {
621 if (mask&(1<<j)) {
622 if (first) first=0;
623 else printk(", ");
624 printk("%s", Usage[j]);
625 }
626 }
627 printk("\n");
628 }
629}
630
631
632
633
634void print_residual_device_info(void)
635{
636 int i;
637 union _PnP_TAG_PACKET *pkt;
638 PPC_DEVICE *dev;
639#define did dev->DeviceId
640
641
642 if (!have_residual_data)
643 return;
644 printk("Residual: %ld devices\n", res->ActualNumDevices);
645 for ( i = 0;
646 i < res->ActualNumDevices ;
647 i++)
648 {
649 dev = &res->Devices[i];
650
651
652
653 if ( did.BusId & PCIDEVICE )
654 {
655 printk("PCI Device:");
656
657 if ( !strncmp( "Unknown", pci_strvendor(did.DevId>>16), 7) )
658 printk(" id %08lx types %d/%d", did.DevId,
659 did.BaseType, did.SubType);
660
661 else
662 printk(" %s %s",
663 pci_strvendor(did.DevId>>16),
664 pci_strdev(did.DevId>>16,
665 did.DevId&0xffff)
666 );
667
668 if ( did.BusId & PNPISADEVICE )
669 {
670 printk(" pnp:");
671
672 pkt = (union _PnP_TAG_PACKET *)
673 &res->DevicePnPHeap[dev->AllocatedOffset];
674 for (; pkt->S1_Pack.Tag != DF_END_TAG;
675 pkt++ )
676 {
677 if ( (pkt->S1_Pack.Tag == S4_Packet) ||
678 (pkt->S1_Pack.Tag == S4_Packet_flags) )
679 printk(" irq %02x%02x",
680 pkt->S4_Pack.IRQMask[0],
681 pkt->S4_Pack.IRQMask[1]);
682 }
683 }
684 printk("\n");
685 continue;
686 }
687
688
689
690 if ( did.BusId & ISADEVICE )
691 {
692 printk("ISA Device: basetype: %d subtype: %d",
693 did.BaseType, did.SubType);
694 printk("\n");
695 continue;
696 }
697
698
699
700 if ( did.BusId & EISADEVICE )
701 {
702 printk("EISA Device: basetype: %d subtype: %d",
703 did.BaseType, did.SubType);
704 printk("\n");
705 continue;
706 }
707
708
709
710 if ( did.BusId & PROCESSORDEVICE )
711 {
712 printk("ProcBus Device: basetype: %d subtype: %d",
713 did.BaseType, did.SubType);
714 printk("\n");
715 continue;
716 }
717
718
719
720 if ( did.BusId & PCMCIADEVICE )
721 {
722 printk("PCMCIA Device: basetype: %d subtype: %d",
723 did.BaseType, did.SubType);
724 printk("\n");
725 continue;
726 }
727 printk("Unknown bus access device: busid %lx\n",
728 did.BusId);
729 }
730}
731#endif
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769static int __init same_DevID(unsigned short vendor,
770 unsigned short Number,
771 char * str)
772{
773 static unsigned const char hexdigit[]="0123456789ABCDEF";
774 if (strlen(str)!=7) return 0;
775 if ( ( ((vendor>>10)&0x1f)+'A'-1 == str[0]) &&
776 ( ((vendor>>5)&0x1f)+'A'-1 == str[1]) &&
777 ( (vendor&0x1f)+'A'-1 == str[2]) &&
778 (hexdigit[(Number>>12)&0x0f] == str[3]) &&
779 (hexdigit[(Number>>8)&0x0f] == str[4]) &&
780 (hexdigit[(Number>>4)&0x0f] == str[5]) &&
781 (hexdigit[Number&0x0f] == str[6]) ) return 1;
782 return 0;
783}
784
785PPC_DEVICE __init *residual_find_device(unsigned long BusMask,
786 unsigned char * DevID,
787 int BaseType,
788 int SubType,
789 int Interface,
790 int n)
791{
792 int i;
793 if (!have_residual_data) return NULL;
794 for (i=0; i<res->ActualNumDevices; i++) {
795#define Dev res->Devices[i].DeviceId
796 if ( (Dev.BusId&BusMask) &&
797 (BaseType==-1 || Dev.BaseType==BaseType) &&
798 (SubType==-1 || Dev.SubType==SubType) &&
799 (Interface==-1 || Dev.Interface==Interface) &&
800 (DevID==NULL || same_DevID((Dev.DevId>>16)&0xffff,
801 Dev.DevId&0xffff, DevID)) &&
802 !(n--) ) return res->Devices+i;
803#undef Dev
804 }
805 return NULL;
806}
807
808PPC_DEVICE __init *residual_find_device_id(unsigned long BusMask,
809 unsigned short DevID,
810 int BaseType,
811 int SubType,
812 int Interface,
813 int n)
814{
815 int i;
816 if (!have_residual_data) return NULL;
817 for (i=0; i<res->ActualNumDevices; i++) {
818#define Dev res->Devices[i].DeviceId
819 if ( (Dev.BusId&BusMask) &&
820 (BaseType==-1 || Dev.BaseType==BaseType) &&
821 (SubType==-1 || Dev.SubType==SubType) &&
822 (Interface==-1 || Dev.Interface==Interface) &&
823 (DevID==0xffff || (Dev.DevId&0xffff) == DevID) &&
824 !(n--) ) return res->Devices+i;
825#undef Dev
826 }
827 return NULL;
828}
829
830static int __init
831residual_scan_pcibridge(PnP_TAG_PACKET * pkt, struct pci_dev *dev)
832{
833 int irq = -1;
834
835#define data pkt->L4_Pack.L4_Data.L4_PPCPack.PPCData
836 if (dev->bus->number == data[16]) {
837 int i, size;
838
839 size = 3 + ld_le16((u_short *) (&pkt->L4_Pack.Count0));
840 for (i = 20; i < size - 4; i += 12) {
841 unsigned char pin;
842 int line_irq;
843
844 if (dev->devfn != data[i + 1])
845 continue;
846
847 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
848 if (pin) {
849 line_irq = ld_le16((unsigned short *)
850 (&data[i + 4 + 2 * (pin - 1)]));
851 irq = (line_irq == 0xffff) ? 0
852 : line_irq & 0x7fff;
853 } else
854 irq = 0;
855
856 break;
857 }
858 }
859#undef data
860
861 return irq;
862}
863
864int __init
865residual_pcidev_irq(struct pci_dev *dev)
866{
867 int i = 0;
868 int irq = -1;
869 PPC_DEVICE *bridge;
870
871 while ((bridge = residual_find_device
872 (-1, NULL, BridgeController, PCIBridge, -1, i++))) {
873
874 PnP_TAG_PACKET *pkt;
875 if (bridge->AllocatedOffset) {
876 pkt = PnP_find_large_vendor_packet(res->DevicePnPHeap +
877 bridge->AllocatedOffset, 3, 0);
878 if (!pkt)
879 continue;
880
881 irq = residual_scan_pcibridge(pkt, dev);
882 if (irq != -1)
883 break;
884 }
885 }
886
887 return (irq < 0) ? 0 : irq;
888}
889
890void __init residual_irq_mask(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
891{
892 PPC_DEVICE *dev;
893 int i = 0;
894 unsigned short irq_mask = 0x000;
895
896 while ((dev = residual_find_device(-1, NULL, -1, -1, -1, i++))) {
897 PnP_TAG_PACKET *pkt;
898 unsigned short mask;
899 int size;
900 int offset = dev->AllocatedOffset;
901
902 if (!offset)
903 continue;
904
905 pkt = PnP_find_packet(res->DevicePnPHeap + offset,
906 IRQFormat, 0);
907 if (!pkt)
908 continue;
909
910 size = tag_small_count(pkt->S1_Pack.Tag) + 1;
911 mask = ld_le16((unsigned short *)pkt->S4_Pack.IRQMask);
912 if (size > 3 && (pkt->S4_Pack.IRQInfo & 0x0c))
913 irq_mask |= mask;
914 }
915
916 *irq_edge_mask_lo = irq_mask & 0xff;
917 *irq_edge_mask_hi = irq_mask >> 8;
918}
919
920unsigned int __init residual_isapic_addr(void)
921{
922 PPC_DEVICE *isapic;
923 PnP_TAG_PACKET *pkt;
924 unsigned int addr;
925
926 isapic = residual_find_device(~0, NULL, SystemPeripheral,
927 ProgrammableInterruptController,
928 ISA_PIC, 0);
929 if (!isapic)
930 goto unknown;
931
932 pkt = PnP_find_large_vendor_packet(res->DevicePnPHeap +
933 isapic->AllocatedOffset, 9, 0);
934 if (!pkt)
935 goto unknown;
936
937#define p pkt->L4_Pack.L4_Data.L4_PPCPack
938
939 if (!((p.PPCData[0] == 3) && (p.PPCData[1] == 32)))
940 goto unknown;
941
942
943 if (ld_le32((unsigned int *)(p.PPCData + 12)) != 1)
944 goto unknown;
945
946 addr = ld_le32((unsigned int *) (p.PPCData + 4));
947#undef p
948 return addr;
949unknown:
950 return 0;
951}
952
953PnP_TAG_PACKET *PnP_find_packet(unsigned char *p,
954 unsigned packet_tag,
955 int n)
956{
957 unsigned mask, masked_tag, size;
958 if(!p) return NULL;
959 if (tag_type(packet_tag)) mask=0xff; else mask=0xF8;
960 masked_tag = packet_tag&mask;
961 for(; *p != END_TAG; p+=size) {
962 if ((*p & mask) == masked_tag && !(n--))
963 return (PnP_TAG_PACKET *) p;
964 if (tag_type(*p))
965 size=ld_le16((unsigned short *)(p+1))+3;
966 else
967 size=tag_small_count(*p)+1;
968 }
969 return NULL;
970}
971
972PnP_TAG_PACKET __init *PnP_find_small_vendor_packet(unsigned char *p,
973 unsigned packet_type,
974 int n)
975{
976 int next=0;
977 while (p) {
978 p = (unsigned char *) PnP_find_packet(p, 0x70, next);
979 if (p && p[1]==packet_type && !(n--))
980 return (PnP_TAG_PACKET *) p;
981 next = 1;
982 };
983 return NULL;
984}
985
986PnP_TAG_PACKET __init *PnP_find_large_vendor_packet(unsigned char *p,
987 unsigned packet_type,
988 int n)
989{
990 int next=0;
991 while (p) {
992 p = (unsigned char *) PnP_find_packet(p, 0x84, next);
993 if (p && p[3]==packet_type && !(n--))
994 return (PnP_TAG_PACKET *) p;
995 next = 1;
996 };
997 return NULL;
998}
999
1000#ifdef CONFIG_PROC_PREPRESIDUAL
1001static int proc_prep_residual_read(char * buf, char ** start, off_t off,
1002 int count, int *eof, void *data)
1003{
1004 int n;
1005
1006 n = res->ResidualLength - off;
1007 if (n < 0) {
1008 *eof = 1;
1009 n = 0;
1010 }
1011 else {
1012 if (n > count)
1013 n = count;
1014 else
1015 *eof = 1;
1016
1017 memcpy(buf, (char *)res + off, n);
1018 *start = buf;
1019 }
1020
1021 return n;
1022}
1023
1024int __init
1025proc_prep_residual_init(void)
1026{
1027 if (have_residual_data)
1028 create_proc_read_entry("residual", S_IRUGO, NULL,
1029 proc_prep_residual_read, NULL);
1030 return 0;
1031}
1032
1033__initcall(proc_prep_residual_init);
1034#endif
1035