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
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
21 #include <linux/string.h>
22 #include <asm/residual.h>
24 #include <asm/byteorder.h>
26 #include <linux/errno.h>
27 #include <linux/sched.h>
28 #include <linux/kernel.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>
46 #include <asm/processor.h>
48 #include <asm/pgtable.h>
49 #include <linux/ide.h>
53 const char * PnP_BASE_TYPES
[] __initdata
= {
56 "NetworkInterfaceController",
58 "MultimediaController",
61 "CommunicationsDevice",
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",
88 "\005\200OtherMemoryDevice",
89 "\006\000HostProcessorBridge",
92 "\006\003MicroChannelBridge",
94 "\006\005PCMCIABridge",
96 "\006\200OtherBridgeDevice",
97 "\007\000RS232Device",
98 "\007\001ATCompatibleParallelPort",
99 "\007\200OtherCommunicationsDevice",
100 "\010\000ProgrammableInterruptController",
101 "\010\001DMAController",
102 "\010\002SystemTimer",
103 "\010\003RealTimeClock",
106 "\010\006PowerManagement",
108 "\010\010OperatorPanel",
109 "\010\011ServiceProcessorClass1",
110 "\010\012ServiceProcessorClass2",
111 "\010\013ServiceProcessorClass3",
112 "\010\014GraphicAssist",
113 "\010\017SystemPlanar",
114 "\010\200OtherSystemPeripheral",
115 "\011\000KeyboardController",
117 "\011\002MouseController",
118 "\011\003TabletController",
119 "\011\0x80OtherInputController",
120 "\012\000GeneralMemoryController",
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",
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",
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",
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 */
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
++;
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
259 && (*s
)[2]==Interface
)) s
++;
264 static void __init
printsmallvendor(PnP_TAG_PACKET
*pkt
, int size
) {
267 #define p pkt->S14_Pack.S14_Data.S14_PPCPack
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);
276 printk(" Chip identification: %s%4.4X\n",
277 decomp
, ld_le16((unsigned short *)(p
.PPCData
+2)));
280 printk(" Small vendor item type 0x%2.2x, data (hex): ",
282 for(i
=0; i
<size
-2; i
++) printk("%2.2x ", p
.PPCData
[i
]);
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
)) {
295 printk(" PnPversion 0x%x.%x\n",
296 pkt
->S1_Pack
.Version
[0], /* How to interpret version ? */
297 pkt
->S1_Pack
.Version
[1]);
299 // case Logicaldevice:
301 // case CompatibleDevice:
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]);
312 #define p pkt->S5_Pack
313 printk(" DMA channel mask 0x%2.2x, info 0x%2.2x\n",
314 p
.DMAMask
, p
.DMAInfo
);
318 printk("Start dependent function:\n");
321 printk("End dependent function\n");
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
),
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);
343 printk(" Undefined packet type %d!\n",
344 tag_small_item_name(pkt
->S1_Pack
.Tag
));
346 case SmallVendorItem
:
347 printsmallvendor(pkt
,size
);
350 printk(" Type 0x2.2x%d, size=%d\n",
351 pkt
->S1_Pack
.Tag
, size
);
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"};
366 #define p pkt->L4_Pack.L4_Data.L4_PPCPack
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));
377 printk(" PCI Bridge parameters\n"
378 " ConfigBaseAddress %0x\n"
379 " ConfigBaseData %0x\n"
381 ld_le32((unsigned int *)p
.PPCData
),
382 ld_le32((unsigned int *)(p
.PPCData
+8)),
384 for(i
=20; i
<size
-4; i
+=12) {
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
);
391 if(first
) first
=0; else *t
++='/';
396 printk(" DevFunc 0x%x interrupt line(s) %s routed to",
397 p
.PPCData
[i
+1],tmpstr
);
399 inttype
[p
.PPCData
[i
+2]-1],
401 printk(" %s line(s) ",
403 for(j
=0, first
=1, t
=tmpstr
; j
<4; j
++) {
404 int line
=ld_le16((unsigned short *)(p
.PPCData
+i
+4)+j
);
406 if(first
) first
=0; else *t
++='/';
407 t
+=sprintf(t
,"%d(%c)",
409 line
&0x8000?'E':'L');
412 printk("%s\n",tmpstr
);
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]);
427 printk(" Bus speed %d Hz, %d slot(s)\n",
428 ld_le32((unsigned int *)p
.PPCData
),
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' : ',');
437 printk(" %s address (%d bits), at 0x%x size 0x%x bytes\n",
438 addrtype
[p
.PPCData
[0]-1],
440 ld_le32((unsigned int *)(p
.PPCData
+4)),
441 ld_le32((unsigned int *)(p
.PPCData
+12)));
445 inttype
[p
.PPCData
[0]-1],
448 printk(" ISA interrupts routed to %s\n"
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
);
458 printk(" Large vendor item type 0x%2.2x\n Data (hex):",
460 for(i
=0; i
<size
-4; i
++) printk(" %2.2x", p
.PPCData
[i
]);
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
);
472 printk(" Type 0x2.2x%d, size=%d\n",
473 pkt
->S1_Pack
.Tag
, size
);
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
);
482 printk( " Packets describing %s resources:\n",cat
);
485 if (tag_type(pkt
->S1_Pack
.Tag
)) {
487 pkt
->L1_Pack
.Count0
+
488 pkt
->L1_Pack
.Count1
*256;
489 printlargepacket(pkt
, size
);
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)
502 #define did dev->DeviceId
504 /* make sure we have residual data first */
505 if ( res
->ResidualLength
== 0 )
508 printk("Residual: %ld devices\n", res
->ActualNumDevices
);
510 i
< res
->ActualNumDevices
;
513 char decomp
[4], sn
[20];
515 dev
= &res
->Devices
[i
];
516 s
= PnP_INTERFACE_STR(did
.BaseType
, did
.SubType
,
519 sprintf(sn
, "interface %d", did
.Interface
);
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);
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
],
554 if ( dev
->PossibleOffset
)
555 printpackets( (union _PnP_TAG_PACKET
*)
556 &res
->DevicePnPHeap
[dev
->PossibleOffset
],
558 if ( dev
->CompatibleOffset
)
559 printpackets( (union _PnP_TAG_PACKET
*)
560 &res
->DevicePnPHeap
[dev
->CompatibleOffset
],
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
--) {
622 printk("%s", Usage
[j
]);
630 * Spit out some info about residual data
632 void print_residual_device_info(void)
635 union _PnP_TAG_PACKET
*pkt
;
637 #define did dev->DeviceId
639 /* make sure we have residual data first */
640 if ( res
->ResidualLength
== 0 )
642 printk("Residual: %ld devices\n", res
->ActualNumDevices
);
644 i
< res
->ActualNumDevices
;
647 dev
= &res
->Devices
[i
];
651 if ( did
.BusId
& PCIDEVICE
)
653 printk("PCI Device:");
655 if ( !strncmp( "Unknown", pci_strvendor(did
.DevId
>>16), 7) )
656 printk(" id %08lx types %d/%d", did
.DevId
,
657 did
.BaseType
, did
.SubType
);
661 pci_strvendor(did
.DevId
>>16),
662 pci_strdev(did
.DevId
>>16,
666 if ( did
.BusId
& PNPISADEVICE
)
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
;
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]);
688 if ( did
.BusId
& ISADEVICE
)
690 printk("ISA Device: basetype: %d subtype: %d",
691 did
.BaseType
, did
.SubType
);
698 if ( did
.BusId
& EISADEVICE
)
700 printk("EISA Device: basetype: %d subtype: %d",
701 did
.BaseType
, did
.SubType
);
708 if ( did
.BusId
& PROCESSORDEVICE
)
710 printk("ProcBus Device: basetype: %d subtype: %d",
711 did
.BaseType
, did
.SubType
);
718 if ( did
.BusId
& PCMCIADEVICE
)
720 printk("PCMCIA Device: basetype: %d subtype: %d",
721 did
.BaseType
, did
.SubType
);
725 printk("Unknown bus access device: busid %lx\n",
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 !
736 - search for the Interrupt controller (8259 type), 2 methods:
737 1) i8259 = residual_find_device(~0,
740 ProgrammableInterruptController,
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,
750 iserial2 = residual_find_device(~0,NULL,
751 CommunicationsDevice,
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
,
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;
783 PPC_DEVICE __init
*residual_find_device(unsigned long BusMask
,
784 unsigned char * DevID
,
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
;
806 PPC_DEVICE __init
*residual_find_device_id(unsigned long BusMask
,
807 unsigned short DevID
,
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
;
828 PnP_TAG_PACKET
*PnP_find_packet(unsigned char *p
,
832 unsigned mask
, masked_tag
, size
;
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
;
840 size
=ld_le16((unsigned short *)(p
+1))+3;
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
,
853 p
= (unsigned char *) PnP_find_packet(p
, 0x70, next
);
854 if (p
&& p
[1]==packet_type
&& !(n
--))
855 return (PnP_TAG_PACKET
*) p
;
858 return 0; /* not found */
861 PnP_TAG_PACKET __init
*PnP_find_large_vendor_packet(unsigned char *p
,
862 unsigned packet_type
,
867 p
= (unsigned char *) PnP_find_packet(p
, 0x84, next
);
868 if (p
&& p
[3]==packet_type
&& !(n
--))
869 return (PnP_TAG_PACKET
*) p
;
872 return 0; /* not found */