Annotation of Gnu-Mach/i386/i386at/gpl/linux/pci/pci.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * drivers/pci/pci.c
        !             3:  *
        !             4:  * PCI services that are built on top of the BIOS32 service.
        !             5:  *
        !             6:  * Copyright 1993, 1994, 1995 Drew Eckhardt, Frederic Potter,
        !             7:  *     David Mosberger-Tang
        !             8:  */
        !             9: #include <linux/config.h>
        !            10: #include <linux/ptrace.h>
        !            11: #include <linux/types.h>
        !            12: #include <linux/kernel.h>
        !            13: #include <linux/bios32.h>
        !            14: #include <linux/pci.h>
        !            15: #include <linux/string.h>
        !            16: 
        !            17: #include <asm/page.h>
        !            18: 
        !            19: struct pci_bus pci_root;
        !            20: struct pci_dev *pci_devices = 0;
        !            21: 
        !            22: 
        !            23: /*
        !            24:  * The bridge_id field is an offset of an item into the array
        !            25:  * BRIDGE_MAPPING_TYPE. 0xff indicates that the device is not a PCI
        !            26:  * bridge, or that we don't know for the moment how to configure it.
        !            27:  * I'm trying to do my best so that the kernel stays small.  Different
        !            28:  * chipset can have same optimization structure. i486 and pentium
        !            29:  * chipsets from the same manufacturer usually have the same
        !            30:  * structure.
        !            31:  */
        !            32: #define DEVICE(vid,did,name) \
        !            33:   {PCI_VENDOR_ID_##vid, PCI_DEVICE_ID_##did, (name), 0xff}
        !            34: 
        !            35: #define BRIDGE(vid,did,name,bridge) \
        !            36:   {PCI_VENDOR_ID_##vid, PCI_DEVICE_ID_##did, (name), (bridge)}
        !            37: 
        !            38: /*
        !            39:  * Sorted in ascending order by vendor and device.
        !            40:  * Use binary search for lookup. If you add a device make sure
        !            41:  * it is sequential by both vendor and device id.
        !            42:  */
        !            43: struct pci_dev_info dev_info[] = {
        !            44:        DEVICE( COMPAQ,         COMPAQ_1280,    "QVision 1280/p"),
        !            45:        DEVICE( COMPAQ,         COMPAQ_THUNDER, "ThunderLAN"),
        !            46:        DEVICE( NCR,            NCR_53C810,     "53c810"),
        !            47:        DEVICE( NCR,            NCR_53C820,     "53c820"),
        !            48:        DEVICE( NCR,            NCR_53C825,     "53c825"),
        !            49:        DEVICE( NCR,            NCR_53C815,     "53c815"),
        !            50:        DEVICE( ATI,            ATI_68800,      "68800AX"),
        !            51:        DEVICE( ATI,            ATI_215CT222,   "215CT222"),
        !            52:        DEVICE( ATI,            ATI_210888CX,   "210888CX"),
        !            53:        DEVICE( ATI,            ATI_210888GX,   "210888GX"),
        !            54:        DEVICE( VLSI,           VLSI_82C592,    "82C592-FC1"),
        !            55:        DEVICE( VLSI,           VLSI_82C593,    "82C593-FC1"),
        !            56:        DEVICE( VLSI,           VLSI_82C594,    "82C594-AFC2"),
        !            57:        DEVICE( VLSI,           VLSI_82C597,    "82C597-AFC2"),
        !            58:        DEVICE( ADL,            ADL_2301,       "2301"),
        !            59:        DEVICE( NS,             NS_87410,       "87410"),
        !            60:        DEVICE( TSENG,          TSENG_W32P_2,   "ET4000W32P"),
        !            61:        DEVICE( TSENG,          TSENG_W32P_b,   "ET4000W32P rev B"),
        !            62:        DEVICE( TSENG,          TSENG_W32P_c,   "ET4000W32P rev C"),
        !            63:        DEVICE( TSENG,          TSENG_W32P_d,   "ET4000W32P rev D"),
        !            64:        DEVICE( WEITEK,         WEITEK_P9000,   "P9000"),
        !            65:        DEVICE( WEITEK,         WEITEK_P9100,   "P9100"),
        !            66:        BRIDGE( DEC,            DEC_BRD,        "DC21050",              0x00),
        !            67:        DEVICE( DEC,            DEC_TULIP,      "DC21040"),
        !            68:        DEVICE( DEC,            DEC_TGA,        "DC21030"),
        !            69:        DEVICE( DEC,            DEC_TULIP_FAST, "DC21140"),
        !            70:        DEVICE( DEC,            DEC_FDDI,       "DEFPA"),
        !            71:        DEVICE( DEC,            DEC_TULIP_PLUS, "DC21041"),
        !            72:        DEVICE( CIRRUS,         CIRRUS_5430,    "GD 5430"),
        !            73:        DEVICE( CIRRUS,         CIRRUS_5434_4,  "GD 5434"),
        !            74:        DEVICE( CIRRUS,         CIRRUS_5434_8,  "GD 5434"),
        !            75:        DEVICE( CIRRUS,         CIRRUS_5436,    "GD 5436"),
        !            76:        DEVICE( CIRRUS,         CIRRUS_6205,    "GD 6205"),
        !            77:        DEVICE( CIRRUS,         CIRRUS_6729,    "CL 6729"),
        !            78:        DEVICE( CIRRUS,         CIRRUS_7542,    "CL 7542"),
        !            79:        DEVICE( CIRRUS,         CIRRUS_7543,    "CL 7543"),
        !            80:        DEVICE( IBM,            IBM_82G2675,    "82G2675"),
        !            81:        DEVICE( WD,             WD_7197,        "WD 7197"),
        !            82:        DEVICE( AMD,            AMD_LANCE,      "79C970"),
        !            83:        DEVICE( AMD,            AMD_SCSI,       "53C974"),
        !            84:        DEVICE( TRIDENT,        TRIDENT_9420,   "TG 9420"),
        !            85:        DEVICE( TRIDENT,        TRIDENT_9440,   "TG 9440"),
        !            86:        DEVICE( TRIDENT,        TRIDENT_9660,   "TG 9660"),
        !            87:        DEVICE( AI,             AI_M1435,       "M1435"),
        !            88:        DEVICE( MATROX,         MATROX_MGA_2,   "Atlas PX2085"),
        !            89:        DEVICE( MATROX,         MATROX_MIL     ,"Millenium"),
        !            90:        DEVICE( MATROX,         MATROX_MGA_IMP, "MGA Impression"),
        !            91:        DEVICE( CT,             CT_65545,       "65545"),
        !            92:        DEVICE( FD,             FD_36C70,       "TMC-18C30"),
        !            93:        DEVICE( SI,             SI_6201,        "6201"),
        !            94:        DEVICE( SI,             SI_6202,        "6202"),
        !            95:        DEVICE( SI,             SI_503,         "85C503"),
        !            96:        DEVICE( SI,             SI_501,         "85C501"),
        !            97:        DEVICE( SI,             SI_496,         "85C496"),
        !            98:        DEVICE( SI,             SI_601,         "85C601"),
        !            99:        DEVICE( SI,             SI_5511,                "85C5511"),
        !           100:        DEVICE( SI,             SI_5513,                "85C5513"),
        !           101:        DEVICE( HP,             HP_J2585A,      "J2585A"),
        !           102:        DEVICE( PCTECH,         PCTECH_RZ1000,  "RZ1000 (buggy)"),
        !           103:        DEVICE( DPT,            DPT,            "SmartCache/Raid"),
        !           104:        DEVICE( OPTI,           OPTI_92C178,    "92C178"),
        !           105:        DEVICE( OPTI,           OPTI_82C557,    "82C557"),
        !           106:        DEVICE( OPTI,           OPTI_82C558,    "82C558"),
        !           107:        DEVICE( OPTI,           OPTI_82C621,    "82C621"),
        !           108:        DEVICE( OPTI,           OPTI_82C822,    "82C822"),
        !           109:        DEVICE( SGS,            SGS_2000,       "STG 2000X"),
        !           110:        DEVICE( SGS,            SGS_1764,       "STG 1764X"),
        !           111:        DEVICE( BUSLOGIC,       BUSLOGIC_946C_2,"BT-946C"),
        !           112:        DEVICE( BUSLOGIC,       BUSLOGIC_946C,  "BT-946C"),
        !           113:        DEVICE( BUSLOGIC,       BUSLOGIC_930,   "BT-930"),
        !           114:        DEVICE( OAK,            OAK_OTI107,     "OTI107"),
        !           115:        DEVICE( PROMISE,        PROMISE_5300,   "DC5030"),
        !           116:        DEVICE( N9,             N9_I128,        "Imagine 128"),
        !           117:        DEVICE( N9,             N9_I128_2,      "Imagine 128v2"),
        !           118:        DEVICE( UMC,            UMC_UM8673F,    "UM8673F"),
        !           119:        BRIDGE( UMC,            UMC_UM8891A,    "UM8891A",              0x01),
        !           120:        DEVICE( UMC,            UMC_UM8886BF,   "UM8886BF"),
        !           121:        DEVICE( UMC,            UMC_UM8886A,    "UM8886A"),
        !           122:        BRIDGE( UMC,            UMC_UM8881F,    "UM8881F",              0x02),
        !           123:        DEVICE( UMC,            UMC_UM8886F,    "UM8886F"),
        !           124:        DEVICE( UMC,            UMC_UM9017F,    "UM9017F"),
        !           125:        DEVICE( UMC,            UMC_UM8886N,    "UM8886N"),
        !           126:        DEVICE( UMC,            UMC_UM8891N,    "UM8891N"),
        !           127:        DEVICE( X,              X_AGX016,       "ITT AGX016"),
        !           128:        DEVICE( NEXGEN,         NEXGEN_82C501,  "82C501"),
        !           129:        DEVICE( QLOGIC,         QLOGIC_ISP1020, "ISP1020"),
        !           130:        DEVICE( QLOGIC,         QLOGIC_ISP1022, "ISP1022"),
        !           131:        DEVICE( LEADTEK,        LEADTEK_805,    "S3 805"),
        !           132:        DEVICE( CONTAQ,         CONTAQ_82C599,  "82C599"),
        !           133:        DEVICE( CMD,            CMD_640,        "640 (buggy)"),
        !           134:        DEVICE( CMD,            CMD_646,        "646"),
        !           135:        DEVICE( VISION,         VISION_QD8500,  "QD-8500"),
        !           136:        DEVICE( VISION,         VISION_QD8580,  "QD-8580"),
        !           137:        DEVICE( SIERRA,         SIERRA_STB,     "STB Horizon 64"),
        !           138:        DEVICE( ACC,            ACC_2056,       "2056"),
        !           139:        DEVICE( WINBOND,        WINBOND_83769,  "W83769F"),
        !           140:        DEVICE( WINBOND,        WINBOND_82C105, "SL82C105"),
        !           141:        DEVICE( 3COM,           3COM_3C590,     "3C590 10bT"),
        !           142:        DEVICE( 3COM,           3COM_3C595TX,   "3C595 100bTX"),
        !           143:        DEVICE( 3COM,           3COM_3C595T4,   "3C595 100bT4"),
        !           144:        DEVICE( 3COM,           3COM_3C595MII,  "3C595 100b-MII"),
        !           145:        DEVICE( AL,             AL_M1445,       "M1445"),
        !           146:        DEVICE( AL,             AL_M1449,       "M1449"),
        !           147:        DEVICE( AL,             AL_M1451,       "M1451"),
        !           148:        DEVICE( AL,             AL_M1461,       "M1461"),
        !           149:        DEVICE( AL,             AL_M1489,       "M1489"),
        !           150:        DEVICE( AL,             AL_M1511,       "M1511"),
        !           151:        DEVICE( AL,             AL_M1513,       "M1513"),
        !           152:        DEVICE( AL,             AL_M4803,       "M4803"),
        !           153:        DEVICE( ASP,            ASP_ABP940,     "ABP940"),
        !           154:        DEVICE( IMS,            IMS_8849,       "8849"),
        !           155:        DEVICE( TEKRAM2,        TEKRAM2_690c,   "DC690c"),
        !           156:        DEVICE( AMCC,           AMCC_MYRINET,   "Myrinet PCI (M2-PCI-32)"),
        !           157:        DEVICE( INTERG,         INTERG_1680,    "IGA-1680"),
        !           158:        DEVICE( REALTEK,        REALTEK_8029,   "8029"),
        !           159:        DEVICE( INIT,           INIT_320P,      "320 P"),
        !           160:        DEVICE( VIA,            VIA_82C505,     "VT 82C505"),
        !           161:        DEVICE( VIA,            VIA_82C561,     "VT 82C561"),
        !           162:        DEVICE( VIA,            VIA_82C576,     "VT 82C576 3V"),
        !           163:        DEVICE( VIA,            VIA_82C416,     "VT 82C416MV"),
        !           164:        DEVICE( VORTEX,         VORTEX_GDT,     "GDT 6000b"),
        !           165:        DEVICE( EF,             EF_ATM_FPGA,            "155P-MF1 (FPGA)"),
        !           166:        DEVICE( EF,             EF_ATM_ASIC,    "155P-MF1 (ASIC)"),
        !           167:        DEVICE( IMAGINGTECH,    IMAGINGTECH_ICPCI, "MVC IC-PCI"),
        !           168:        DEVICE( FORE,           FORE_PCA200PC, "PCA-200PC"),
        !           169:        DEVICE( PLX,            PLX_9060,       "PCI9060 i960 bridge"),
        !           170:        DEVICE( ALLIANCE,       ALLIANCE_PROMOTIO, "Promotion-6410"),
        !           171:        DEVICE( ALLIANCE,       ALLIANCE_PROVIDEO, "Provideo"),
        !           172:        DEVICE( MUTECH,         MUTECH_MV1000,  "MV-1000"),
        !           173:        DEVICE( ZEITNET,        ZEITNET_1221,   "1221"),
        !           174:        DEVICE( ZEITNET,        ZEITNET_1225,   "1225"),
        !           175:        DEVICE( SPECIALIX,      SPECIALIX_XIO,  "XIO/SIO host"),
        !           176:        DEVICE( SPECIALIX,      SPECIALIX_RIO,  "RIO host"),
        !           177:        DEVICE( RP,             RP8OCTA,        "RocketPort 8 Oct"),
        !           178:        DEVICE( RP,             RP8INTF,        "RocketPort 8 Intf"),
        !           179:        DEVICE( RP,             RP16INTF,       "RocketPort 16 Intf"),
        !           180:        DEVICE( RP,             RP32INTF,       "RocketPort 32 Intf"),
        !           181:        DEVICE( CYCLADES,       CYCLADES_Y,     "Cyclome-Y"),
        !           182:        DEVICE( SYMPHONY,       SYMPHONY_101,   "82C101"),
        !           183:        DEVICE( TEKRAM,         TEKRAM_DC290,   "DC-290"),
        !           184:        DEVICE( AVANCE,         AVANCE_2302,    "ALG-2302"),
        !           185:        DEVICE( S3,             S3_811,         "Trio32/Trio64"),
        !           186:        DEVICE( S3,             S3_868, "Vision 868"),
        !           187:        DEVICE( S3,             S3_928,         "Vision 928-P"),
        !           188:        DEVICE( S3,             S3_864_1,       "Vision 864-P"),
        !           189:        DEVICE( S3,             S3_864_2,       "Vision 864-P"),
        !           190:        DEVICE( S3,             S3_964_1,       "Vision 964-P"),
        !           191:        DEVICE( S3,             S3_964_2,       "Vision 964-P"),
        !           192:        DEVICE( S3,             S3_968,         "Vision 968"),
        !           193:        DEVICE( INTEL,          INTEL_82375,    "82375EB"),
        !           194:        BRIDGE( INTEL,          INTEL_82424,    "82424ZX Saturn",       0x00),
        !           195:        DEVICE( INTEL,          INTEL_82378,    "82378IB"),
        !           196:        DEVICE( INTEL,          INTEL_82430,    "82430ZX Aries"),
        !           197:        BRIDGE( INTEL,          INTEL_82434,    "82434LX Mercury/Neptune", 0x00),
        !           198:        DEVICE( INTEL,          INTEL_7116,     "SAA7116"),
        !           199:        DEVICE( INTEL,          INTEL_82596,    "82596"),
        !           200:        DEVICE( INTEL,          INTEL_82865,    "82865"),
        !           201:        DEVICE( INTEL,          INTEL_82557,    "82557"),
        !           202:        DEVICE( INTEL,          INTEL_82437,    "82437"),
        !           203:        DEVICE( INTEL,          INTEL_82371_0,  "82371 Triton PIIX"),
        !           204:        DEVICE( INTEL,          INTEL_82371_1,  "82371 Triton PIIX"),
        !           205:        DEVICE( INTEL,          INTEL_P6,       "Orion P6"),
        !           206:        DEVICE( ADAPTEC,        ADAPTEC_7850,   "AIC-7850"),
        !           207:        DEVICE( ADAPTEC,        ADAPTEC_7870,   "AIC-7870"),
        !           208:        DEVICE( ADAPTEC,        ADAPTEC_7871,   "AIC-7871"),
        !           209:        DEVICE( ADAPTEC,        ADAPTEC_7872,   "AIC-7872"),
        !           210:        DEVICE( ADAPTEC,        ADAPTEC_7873,   "AIC-7873"),
        !           211:        DEVICE( ADAPTEC,        ADAPTEC_7874,   "AIC-7874"),
        !           212:        DEVICE( ADAPTEC,        ADAPTEC_7880,   "AIC-7880U"),
        !           213:        DEVICE( ADAPTEC,        ADAPTEC_7881,   "AIC-7881U"),
        !           214:        DEVICE( ADAPTEC,        ADAPTEC_7882,   "AIC-7882U"),
        !           215:        DEVICE( ADAPTEC,        ADAPTEC_7883,   "AIC-7883U"),
        !           216:        DEVICE( ADAPTEC,        ADAPTEC_7884,   "AIC-7884U"),
        !           217:        DEVICE( ATRONICS,       ATRONICS_2015,  "IDE-2015PL"),
        !           218:        DEVICE( HER,            HER_STING,      "Stingray"),
        !           219:        DEVICE( HER,            HER_STINGARK,   "Stingray ARK 2000PV")
        !           220: };
        !           221: 
        !           222: 
        !           223: #ifdef CONFIG_PCI_OPTIMIZE
        !           224: 
        !           225: /*
        !           226:  * An item of this structure has the following meaning:
        !           227:  * for each optimization, the register address, the mask
        !           228:  * and value to write to turn it on.
        !           229:  * There are 5 optimizations for the moment:
        !           230:  * Cache L2 write back best than write through
        !           231:  * Posted Write for CPU to PCI enable
        !           232:  * Posted Write for CPU to MEMORY enable
        !           233:  * Posted Write for PCI to MEMORY enable
        !           234:  * PCI Burst enable
        !           235:  *
        !           236:  * Half of the bios I've meet don't allow you to turn that on, and you
        !           237:  * can gain more than 15% on graphic accesses using those
        !           238:  * optimizations...
        !           239:  */
        !           240: struct optimization_type {
        !           241:        const char      *type;
        !           242:        const char      *off;
        !           243:        const char      *on;
        !           244: } bridge_optimization[] = {
        !           245:        {"Cache L2",                    "write through",        "write back"},
        !           246:        {"CPU-PCI posted write",        "off",          "on"},
        !           247:        {"CPU-Memory posted write",     "off",          "on"},
        !           248:        {"PCI-Memory posted write",     "off",          "on"},
        !           249:        {"PCI burst",                   "off",          "on"}
        !           250: };
        !           251: 
        !           252: #define NUM_OPTIMIZATIONS \
        !           253:        (sizeof(bridge_optimization) / sizeof(bridge_optimization[0]))
        !           254: 
        !           255: struct bridge_mapping_type {
        !           256:        unsigned char   addr;   /* config space address */
        !           257:        unsigned char   mask;
        !           258:        unsigned char   value;
        !           259: } bridge_mapping[] = {
        !           260:        /*
        !           261:         * Intel Neptune/Mercury/Saturn:
        !           262:         *      If the internal cache is write back,
        !           263:         *      the L2 cache must be write through!
        !           264:         *      I've to check out how to control that
        !           265:         *      for the moment, we won't touch the cache
        !           266:         */
        !           267:        {0x0    ,0x02   ,0x02   },
        !           268:        {0x53   ,0x02   ,0x02   },
        !           269:        {0x53   ,0x01   ,0x01   },
        !           270:        {0x54   ,0x01   ,0x01   },
        !           271:        {0x54   ,0x02   ,0x02   },
        !           272: 
        !           273:        /*
        !           274:         * UMC 8891A Pentium chipset:
        !           275:         *      Why did you think UMC was cheaper ??
        !           276:         */
        !           277:        {0x50   ,0x10   ,0x00   },
        !           278:        {0x51   ,0x40   ,0x40   },
        !           279:        {0x0    ,0x0    ,0x0    },
        !           280:        {0x0    ,0x0    ,0x0    },
        !           281:        {0x0    ,0x0    ,0x0    },
        !           282: 
        !           283:        /*
        !           284:         * UMC UM8881F
        !           285:         *      This is a dummy entry for my tests.
        !           286:         *      I have this chipset and no docs....
        !           287:         */
        !           288:        {0x0    ,0x1    ,0x1    },
        !           289:        {0x0    ,0x2    ,0x0    },
        !           290:        {0x0    ,0x0    ,0x0    },
        !           291:        {0x0    ,0x0    ,0x0    },
        !           292:        {0x0    ,0x0    ,0x0    }
        !           293: };
        !           294: 
        !           295: #endif /* CONFIG_PCI_OPTIMIZE */
        !           296: 
        !           297: 
        !           298: /*
        !           299:  * device_info[] is sorted so we can use binary search
        !           300:  */
        !           301: struct pci_dev_info *pci_lookup_dev(unsigned int vendor, unsigned int dev)
        !           302: {
        !           303:        int min = 0,
        !           304:            max = sizeof(dev_info)/sizeof(dev_info[0]) - 1;
        !           305: 
        !           306:        for ( ; ; )
        !           307:        {
        !           308:            int i = (min + max) >> 1;
        !           309:            long order;
        !           310: 
        !           311:            order = dev_info[i].vendor - (long) vendor;
        !           312:            if (!order)
        !           313:                order = dev_info[i].device - (long) dev;
        !           314:        
        !           315:            if (order < 0)
        !           316:            {
        !           317:                    min = i + 1;
        !           318:                    if ( min > max )
        !           319:                       return 0;
        !           320:                    continue;
        !           321:            }
        !           322: 
        !           323:            if (order > 0)
        !           324:            {
        !           325:                    max = i - 1;
        !           326:                    if ( min > max )
        !           327:                       return 0;
        !           328:                    continue;
        !           329:            }
        !           330: 
        !           331:            return & dev_info[ i ];
        !           332:        }
        !           333: }
        !           334: 
        !           335: const char *pci_strclass (unsigned int class)
        !           336: {
        !           337:        switch (class >> 8) {
        !           338:              case PCI_CLASS_NOT_DEFINED:               return "Non-VGA device";
        !           339:              case PCI_CLASS_NOT_DEFINED_VGA:           return "VGA compatible device";
        !           340: 
        !           341:              case PCI_CLASS_STORAGE_SCSI:              return "SCSI storage controller";
        !           342:              case PCI_CLASS_STORAGE_IDE:               return "IDE interface";
        !           343:              case PCI_CLASS_STORAGE_FLOPPY:            return "Floppy disk controller";
        !           344:              case PCI_CLASS_STORAGE_IPI:               return "IPI bus controller";
        !           345:              case PCI_CLASS_STORAGE_RAID:              return "RAID bus controller";
        !           346:              case PCI_CLASS_STORAGE_OTHER:             return "Unknown mass storage controller";
        !           347: 
        !           348:              case PCI_CLASS_NETWORK_ETHERNET:          return "Ethernet controller";
        !           349:              case PCI_CLASS_NETWORK_TOKEN_RING:        return "Token ring network controller";
        !           350:              case PCI_CLASS_NETWORK_FDDI:              return "FDDI network controller";
        !           351:              case PCI_CLASS_NETWORK_ATM:               return "ATM network controller";
        !           352:              case PCI_CLASS_NETWORK_OTHER:             return "Network controller";
        !           353: 
        !           354:              case PCI_CLASS_DISPLAY_VGA:               return "VGA compatible controller";
        !           355:              case PCI_CLASS_DISPLAY_XGA:               return "XGA compatible controller";
        !           356:              case PCI_CLASS_DISPLAY_OTHER:             return "Display controller";
        !           357: 
        !           358:              case PCI_CLASS_MULTIMEDIA_VIDEO:          return "Multimedia video controller";
        !           359:              case PCI_CLASS_MULTIMEDIA_AUDIO:          return "Multimedia audio controller";
        !           360:              case PCI_CLASS_MULTIMEDIA_OTHER:          return "Multimedia controller";
        !           361: 
        !           362:              case PCI_CLASS_MEMORY_RAM:                return "RAM memory";
        !           363:              case PCI_CLASS_MEMORY_FLASH:              return "FLASH memory";
        !           364:              case PCI_CLASS_MEMORY_OTHER:              return "Memory";
        !           365: 
        !           366:              case PCI_CLASS_BRIDGE_HOST:               return "Host bridge";
        !           367:              case PCI_CLASS_BRIDGE_ISA:                return "ISA bridge";
        !           368:              case PCI_CLASS_BRIDGE_EISA:               return "EISA bridge";
        !           369:              case PCI_CLASS_BRIDGE_MC:                 return "MicroChannel bridge";
        !           370:              case PCI_CLASS_BRIDGE_PCI:                return "PCI bridge";
        !           371:              case PCI_CLASS_BRIDGE_PCMCIA:             return "PCMCIA bridge";
        !           372:              case PCI_CLASS_BRIDGE_NUBUS:              return "NuBus bridge";
        !           373:              case PCI_CLASS_BRIDGE_CARDBUS:            return "CardBus bridge";
        !           374:              case PCI_CLASS_BRIDGE_OTHER:              return "Bridge";
        !           375: 
        !           376:              case PCI_CLASS_COMMUNICATION_SERIAL:      return "Serial controller";
        !           377:              case PCI_CLASS_COMMUNICATION_PARALLEL:    return "Parallel controller";
        !           378:              case PCI_CLASS_COMMUNICATION_OTHER:       return "Communication controller";
        !           379: 
        !           380:              case PCI_CLASS_SYSTEM_PIC:                return "PIC";
        !           381:              case PCI_CLASS_SYSTEM_DMA:                return "DMA controller";
        !           382:              case PCI_CLASS_SYSTEM_TIMER:              return "Timer";
        !           383:              case PCI_CLASS_SYSTEM_RTC:                return "RTC";
        !           384:              case PCI_CLASS_SYSTEM_OTHER:              return "System peripheral";
        !           385: 
        !           386:              case PCI_CLASS_INPUT_KEYBOARD:            return "Keyboard controller";
        !           387:              case PCI_CLASS_INPUT_PEN:                 return "Digitizer Pen";
        !           388:              case PCI_CLASS_INPUT_MOUSE:               return "Mouse controller";
        !           389:              case PCI_CLASS_INPUT_OTHER:               return "Input device controller";
        !           390: 
        !           391:              case PCI_CLASS_DOCKING_GENERIC:           return "Generic Docking Station";
        !           392:              case PCI_CLASS_DOCKING_OTHER:             return "Docking Station";
        !           393: 
        !           394:              case PCI_CLASS_PROCESSOR_386:             return "386";
        !           395:              case PCI_CLASS_PROCESSOR_486:             return "486";
        !           396:              case PCI_CLASS_PROCESSOR_PENTIUM:         return "Pentium";
        !           397:              case PCI_CLASS_PROCESSOR_ALPHA:           return "Alpha";
        !           398:              case PCI_CLASS_PROCESSOR_POWERPC:         return "Power PC";
        !           399:              case PCI_CLASS_PROCESSOR_CO:              return "Co-processor";
        !           400: 
        !           401:              case PCI_CLASS_SERIAL_FIREWIRE:           return "FireWire (IEEE 1394)";
        !           402:              case PCI_CLASS_SERIAL_ACCESS:             return "ACCESS Bus";
        !           403:              case PCI_CLASS_SERIAL_SSA:                return "SSA";
        !           404:              case PCI_CLASS_SERIAL_FIBER:              return "Fiber Channel";
        !           405: 
        !           406:              default:                                  return "Unknown class";
        !           407:        }
        !           408: }
        !           409: 
        !           410: 
        !           411: const char *pci_strvendor(unsigned int vendor)
        !           412: {
        !           413:        switch (vendor) {
        !           414:              case PCI_VENDOR_ID_COMPAQ:        return "Compaq";
        !           415:              case PCI_VENDOR_ID_NCR:           return "NCR";
        !           416:              case PCI_VENDOR_ID_ATI:           return "ATI";
        !           417:              case PCI_VENDOR_ID_VLSI:          return "VLSI";
        !           418:              case PCI_VENDOR_ID_ADL:           return "Advance Logic";
        !           419:              case PCI_VENDOR_ID_NS:            return "NS";
        !           420:              case PCI_VENDOR_ID_TSENG:         return "Tseng'Lab";
        !           421:              case PCI_VENDOR_ID_WEITEK:        return "Weitek";
        !           422:              case PCI_VENDOR_ID_DEC:           return "DEC";
        !           423:              case PCI_VENDOR_ID_CIRRUS:        return "Cirrus Logic";
        !           424:              case PCI_VENDOR_ID_IBM:           return "IBM";
        !           425:              case PCI_VENDOR_ID_WD:            return "Western Digital";
        !           426:              case PCI_VENDOR_ID_AMD:           return "AMD";
        !           427:              case PCI_VENDOR_ID_TRIDENT:       return "Trident";
        !           428:              case PCI_VENDOR_ID_AI:            return "Acer Incorporated";
        !           429:              case PCI_VENDOR_ID_MATROX:        return "Matrox";
        !           430:              case PCI_VENDOR_ID_CT:            return "Chips & Technologies";
        !           431:              case PCI_VENDOR_ID_FD:            return "Future Domain";
        !           432:              case PCI_VENDOR_ID_SI:            return "Silicon Integrated Systems";
        !           433:              case PCI_VENDOR_ID_HP:            return "Hewlett Packard";
        !           434:              case PCI_VENDOR_ID_PCTECH:        return "PCTECH";
        !           435:              case PCI_VENDOR_ID_DPT:           return "DPT";
        !           436:              case PCI_VENDOR_ID_OPTI:          return "OPTI";
        !           437:              case PCI_VENDOR_ID_SGS:           return "SGS Thomson";
        !           438:              case PCI_VENDOR_ID_BUSLOGIC:      return "BusLogic";
        !           439:              case PCI_VENDOR_ID_OAK:           return "OAK";
        !           440:              case PCI_VENDOR_ID_PROMISE:       return "Promise Technology";
        !           441:              case PCI_VENDOR_ID_N9:            return "Number Nine";
        !           442:              case PCI_VENDOR_ID_UMC:           return "UMC";
        !           443:              case PCI_VENDOR_ID_X:             return "X TECHNOLOGY";
        !           444:              case PCI_VENDOR_ID_NEXGEN:        return "Nexgen";
        !           445:              case PCI_VENDOR_ID_QLOGIC:        return "Q Logic";
        !           446:              case PCI_VENDOR_ID_LEADTEK:       return "Leadtek Research";
        !           447:              case PCI_VENDOR_ID_CONTAQ:        return "Contaq";
        !           448:              case PCI_VENDOR_ID_FOREX:         return "Forex";
        !           449:              case PCI_VENDOR_ID_OLICOM:        return "Olicom";
        !           450:              case PCI_VENDOR_ID_CMD:           return "CMD";
        !           451:              case PCI_VENDOR_ID_VISION:        return "Vision";
        !           452:              case PCI_VENDOR_ID_SIERRA:        return "Sierra";
        !           453:              case PCI_VENDOR_ID_ACC:           return "ACC MICROELECTRONICS";
        !           454:              case PCI_VENDOR_ID_WINBOND:       return "Winbond";
        !           455:              case PCI_VENDOR_ID_3COM:          return "3Com";
        !           456:              case PCI_VENDOR_ID_AL:            return "Acer Labs";
        !           457:              case PCI_VENDOR_ID_ASP:           return "Advanced System Products";
        !           458:              case PCI_VENDOR_ID_IMS:           return "IMS";
        !           459:              case PCI_VENDOR_ID_TEKRAM2:       return "Tekram";
        !           460:              case PCI_VENDOR_ID_AMCC:          return "AMCC";
        !           461:              case PCI_VENDOR_ID_INTERG:        return "Intergraphics";
        !           462:              case PCI_VENDOR_ID_REALTEK:       return "Realtek";
        !           463:              case PCI_VENDOR_ID_INIT:          return "Initio Corp";
        !           464:              case PCI_VENDOR_ID_VIA:           return "VIA Technologies";
        !           465:              case PCI_VENDOR_ID_VORTEX:        return "VORTEX";
        !           466:              case PCI_VENDOR_ID_EF:            return "Efficient Networks";
        !           467:              case PCI_VENDOR_ID_FORE:          return "Fore Systems";
        !           468:              case PCI_VENDOR_ID_IMAGINGTECH:   return "Imaging Technology";
        !           469:              case PCI_VENDOR_ID_PLX:           return "PLX";
        !           470:              case PCI_VENDOR_ID_ALLIANCE:      return "Alliance";
        !           471:              case PCI_VENDOR_ID_MUTECH:        return "Mutech";
        !           472:              case PCI_VENDOR_ID_ZEITNET:       return "ZeitNet";
        !           473:              case PCI_VENDOR_ID_SPECIALIX:     return "Specialix";
        !           474:              case PCI_VENDOR_ID_RP:            return "Comtrol";
        !           475:              case PCI_VENDOR_ID_CYCLADES:      return "Cyclades";
        !           476:              case PCI_VENDOR_ID_SYMPHONY:      return "Symphony";
        !           477:              case PCI_VENDOR_ID_TEKRAM:        return "Tekram";
        !           478:              case PCI_VENDOR_ID_AVANCE:        return "Avance";
        !           479:              case PCI_VENDOR_ID_S3:            return "S3 Inc.";
        !           480:              case PCI_VENDOR_ID_INTEL:         return "Intel";
        !           481:              case PCI_VENDOR_ID_ADAPTEC:       return "Adaptec";
        !           482:              case PCI_VENDOR_ID_ATRONICS:      return "Atronics";
        !           483:              case PCI_VENDOR_ID_HER:           return "Hercules";
        !           484:              default:                          return "Unknown vendor";
        !           485:        }
        !           486: }
        !           487: 
        !           488: 
        !           489: const char *pci_strdev(unsigned int vendor, unsigned int device)
        !           490: {
        !           491:        struct pci_dev_info *info;
        !           492: 
        !           493:        info =  pci_lookup_dev(vendor, device);
        !           494:        return info ? info->name : "Unknown device";
        !           495: }
        !           496: 
        !           497: 
        !           498: 
        !           499: /*
        !           500:  * Turn on/off PCI bridge optimization. This should allow benchmarking.
        !           501:  */
        !           502: static void burst_bridge(unsigned char bus, unsigned char devfn,
        !           503:                         unsigned char pos, int turn_on)
        !           504: {
        !           505: #ifdef CONFIG_PCI_OPTIMIZE
        !           506:        struct bridge_mapping_type *bmap;
        !           507:        unsigned char val;
        !           508:        int i;
        !           509: 
        !           510:        pos *= NUM_OPTIMIZATIONS;
        !           511:        printk("PCI bridge optimization.\n");
        !           512:        for (i = 0; i < NUM_OPTIMIZATIONS; i++) {
        !           513:                printk("    %s: ", bridge_optimization[i].type);
        !           514:                bmap = &bridge_mapping[pos + i];
        !           515:                if (!bmap->addr) {
        !           516:                        printk("Not supported.");
        !           517:                } else {
        !           518:                        pcibios_read_config_byte(bus, devfn, bmap->addr, &val);
        !           519:                        if ((val & bmap->mask) == bmap->value) {
        !           520:                                printk("%s.", bridge_optimization[i].on);
        !           521:                                if (!turn_on) {
        !           522:                                        pcibios_write_config_byte(bus, devfn,
        !           523:                                                                  bmap->addr,
        !           524:                                                                  (val | bmap->mask)
        !           525:                                                                  - bmap->value);
        !           526:                                        printk("Changed!  Now %s.", bridge_optimization[i].off);
        !           527:                                }
        !           528:                        } else {
        !           529:                                printk("%s.", bridge_optimization[i].off);
        !           530:                                if (turn_on) {
        !           531:                                        pcibios_write_config_byte(bus, devfn,
        !           532:                                                                  bmap->addr,
        !           533:                                                                  (val & (0xff - bmap->mask))
        !           534:                                                                  + bmap->value);
        !           535:                                        printk("Changed!  Now %s.", bridge_optimization[i].on);
        !           536:                                }
        !           537:                        }
        !           538:                }
        !           539:                printk("\n");
        !           540:        }
        !           541: #endif /* CONFIG_PCI_OPTIMIZE */
        !           542: }
        !           543: 
        !           544: 
        !           545: /*
        !           546:  * Convert some of the configuration space registers of the device at
        !           547:  * address (bus,devfn) into a string (possibly several lines each).
        !           548:  * The configuration string is stored starting at buf[len].  If the
        !           549:  * string would exceed the size of the buffer (SIZE), 0 is returned.
        !           550:  */
        !           551: static int sprint_dev_config(struct pci_dev *dev, char *buf, int size)
        !           552: {
        !           553:        unsigned long base;
        !           554:        unsigned int l, class_rev, bus, devfn;
        !           555:        unsigned short vendor, device, status;
        !           556:        unsigned char bist, latency, min_gnt, max_lat;
        !           557:        int reg, len = 0;
        !           558:        const char *str;
        !           559: 
        !           560:        bus   = dev->bus->number;
        !           561:        devfn = dev->devfn;
        !           562: 
        !           563:        pcibios_read_config_dword(bus, devfn, PCI_CLASS_REVISION, &class_rev);
        !           564:        pcibios_read_config_word (bus, devfn, PCI_VENDOR_ID, &vendor);
        !           565:        pcibios_read_config_word (bus, devfn, PCI_DEVICE_ID, &device);
        !           566:        pcibios_read_config_word (bus, devfn, PCI_STATUS, &status);
        !           567:        pcibios_read_config_byte (bus, devfn, PCI_BIST, &bist);
        !           568:        pcibios_read_config_byte (bus, devfn, PCI_LATENCY_TIMER, &latency);
        !           569:        pcibios_read_config_byte (bus, devfn, PCI_MIN_GNT, &min_gnt);
        !           570:        pcibios_read_config_byte (bus, devfn, PCI_MAX_LAT, &max_lat);
        !           571:        if (len + 80 > size) {
        !           572:                return -1;
        !           573:        }
        !           574:        len += sprintf(buf + len, "  Bus %2d, device %3d, function %2d:\n",
        !           575:                       bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
        !           576: 
        !           577:        if (len + 80 > size) {
        !           578:                return -1;
        !           579:        }
        !           580:        len += sprintf(buf + len, "    %s: %s %s (rev %d).\n      ",
        !           581:                       pci_strclass(class_rev >> 8), pci_strvendor(vendor),
        !           582:                       pci_strdev(vendor, device), class_rev & 0xff);
        !           583: 
        !           584:        if (!pci_lookup_dev(vendor, device)) {
        !           585:                len += sprintf(buf + len,
        !           586:                               "Vendor id=%x. Device id=%x.\n      ",
        !           587:                               vendor, device);
        !           588:        }
        !           589: 
        !           590:        str = 0;        /* to keep gcc shut... */
        !           591:        switch (status & PCI_STATUS_DEVSEL_MASK) {
        !           592:              case PCI_STATUS_DEVSEL_FAST:   str = "Fast devsel.  "; break;
        !           593:              case PCI_STATUS_DEVSEL_MEDIUM: str = "Medium devsel.  "; break;
        !           594:              case PCI_STATUS_DEVSEL_SLOW:   str = "Slow devsel.  "; break;
        !           595:        }
        !           596:        if (len + strlen(str) > size) {
        !           597:                return -1;
        !           598:        }
        !           599:        len += sprintf(buf + len, str);
        !           600: 
        !           601:        if (status & PCI_STATUS_FAST_BACK) {
        !           602: #              define fast_b2b_capable "Fast back-to-back capable.  "
        !           603:                if (len + strlen(fast_b2b_capable) > size) {
        !           604:                        return -1;
        !           605:                }
        !           606:                len += sprintf(buf + len, fast_b2b_capable);
        !           607: #              undef fast_b2b_capable
        !           608:        }
        !           609: 
        !           610:        if (bist & PCI_BIST_CAPABLE) {
        !           611: #              define BIST_capable     "BIST capable.  "
        !           612:                if (len + strlen(BIST_capable) > size) {
        !           613:                        return -1;
        !           614:                }
        !           615:                len += sprintf(buf + len, BIST_capable);
        !           616: #              undef BIST_capable
        !           617:        }
        !           618: 
        !           619:        if (dev->irq) {
        !           620:                if (len + 40 > size) {
        !           621:                        return -1;
        !           622:                }
        !           623:                len += sprintf(buf + len, "IRQ %d.  ", dev->irq);
        !           624:        }
        !           625: 
        !           626:        if (dev->master) {
        !           627:                if (len + 80 > size) {
        !           628:                        return -1;
        !           629:                }
        !           630:                len += sprintf(buf + len, "Master Capable.  ");
        !           631:                if (latency)
        !           632:                  len += sprintf(buf + len, "Latency=%d.  ", latency);
        !           633:                else
        !           634:                  len += sprintf(buf + len, "No bursts.  ");
        !           635:                if (min_gnt)
        !           636:                  len += sprintf(buf + len, "Min Gnt=%d.", min_gnt);
        !           637:                if (max_lat)
        !           638:                  len += sprintf(buf + len, "Max Lat=%d.", max_lat);
        !           639:        }
        !           640: 
        !           641:        for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
        !           642:                if (len + 40 > size) {
        !           643:                        return -1;
        !           644:                }
        !           645:                pcibios_read_config_dword(bus, devfn, reg, &l);
        !           646:                base = l;
        !           647:                if (!base) {
        !           648:                        continue;
        !           649:                }
        !           650: 
        !           651:                if (base & PCI_BASE_ADDRESS_SPACE_IO) {
        !           652:                        len += sprintf(buf + len,
        !           653:                                       "\n      I/O at 0x%lx.",
        !           654:                                       base & PCI_BASE_ADDRESS_IO_MASK);
        !           655:                } else {
        !           656:                        const char *pref, *type = "unknown";
        !           657: 
        !           658:                        if (base & PCI_BASE_ADDRESS_MEM_PREFETCH) {
        !           659:                                pref = "P";
        !           660:                        } else {
        !           661:                                pref = "Non-p";
        !           662:                        }
        !           663:                        switch (base & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
        !           664:                              case PCI_BASE_ADDRESS_MEM_TYPE_32:
        !           665:                                type = "32 bit"; break;
        !           666:                              case PCI_BASE_ADDRESS_MEM_TYPE_1M:
        !           667:                                type = "20 bit"; break;
        !           668:                              case PCI_BASE_ADDRESS_MEM_TYPE_64:
        !           669:                                type = "64 bit";
        !           670:                                /* read top 32 bit address of base addr: */
        !           671:                                reg += 4;
        !           672:                                pcibios_read_config_dword(bus, devfn, reg, &l);
        !           673:                                base |= ((u64) l) << 32;
        !           674:                                break;
        !           675:                        }
        !           676:                        len += sprintf(buf + len,
        !           677:                                       "\n      %srefetchable %s memory at "
        !           678:                                       "0x%lx.", pref, type,
        !           679:                                       base & PCI_BASE_ADDRESS_MEM_MASK);
        !           680:                }
        !           681:        }
        !           682: 
        !           683:        len += sprintf(buf + len, "\n");
        !           684:        return len;
        !           685: }
        !           686: 
        !           687: 
        !           688: /*
        !           689:  * Return list of PCI devices as a character string for /proc/pci.
        !           690:  * BUF is a buffer that is PAGE_SIZE bytes long.
        !           691:  */
        !           692: int get_pci_list(char *buf)
        !           693: {
        !           694:        int nprinted, len, size;
        !           695:        struct pci_dev *dev;
        !           696: #      define MSG "\nwarning: page-size limit reached!\n"
        !           697: 
        !           698:        /* reserve same for truncation warning message: */
        !           699:        size  = PAGE_SIZE - (strlen(MSG) + 1);
        !           700:        len   = sprintf(buf, "PCI devices found:\n");
        !           701: 
        !           702:        for (dev = pci_devices; dev; dev = dev->next) {
        !           703:                nprinted = sprint_dev_config(dev, buf + len, size - len);
        !           704:                if (nprinted < 0) {
        !           705:                        return len + sprintf(buf + len, MSG);
        !           706:                }
        !           707:                len += nprinted;
        !           708:        }
        !           709:        return len;
        !           710: }
        !           711: 
        !           712: 
        !           713: /*
        !           714:  * pci_malloc() returns initialized memory of size SIZE.  Can be
        !           715:  * used only while pci_init() is active.
        !           716:  */
        !           717: static void *pci_malloc(long size, unsigned long *mem_startp)
        !           718: {
        !           719:        void *mem;
        !           720: 
        !           721: #ifdef DEBUG
        !           722:        printk("...pci_malloc(size=%ld,mem=%p)", size, *mem_startp);
        !           723: #endif
        !           724:        mem = (void*) *mem_startp;
        !           725:        *mem_startp += (size + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
        !           726:        memset(mem, 0, size);
        !           727:        return mem;
        !           728: }
        !           729: 
        !           730: 
        !           731: static unsigned int scan_bus(struct pci_bus *bus, unsigned long *mem_startp)
        !           732: {
        !           733:        unsigned int devfn, l, max;
        !           734:        unsigned char cmd, tmp, hdr_type = 0;
        !           735:        struct pci_dev_info *info;
        !           736:        struct pci_dev *dev;
        !           737:        struct pci_bus *child;
        !           738: 
        !           739: #ifdef DEBUG
        !           740:        printk("...scan_bus(busno=%d,mem=%p)\n", bus->number, *mem_startp);
        !           741: #endif
        !           742: 
        !           743:        max = bus->secondary;
        !           744:        for (devfn = 0; devfn < 0xff; ++devfn) {
        !           745:                if (PCI_FUNC(devfn) == 0) {
        !           746:                        pcibios_read_config_byte(bus->number, devfn,
        !           747:                                                 PCI_HEADER_TYPE, &hdr_type);
        !           748:                } else if (!(hdr_type & 0x80)) {
        !           749:                        /* not a multi-function device */
        !           750:                        continue;
        !           751:                }
        !           752: 
        !           753:                pcibios_read_config_dword(bus->number, devfn, PCI_VENDOR_ID,
        !           754:                                          &l);
        !           755:                /* some broken boards return 0 if a slot is empty: */
        !           756:                if (l == 0xffffffff || l == 0x00000000) {
        !           757:                        hdr_type = 0;
        !           758:                        continue;
        !           759:                }
        !           760: 
        !           761:                dev = pci_malloc(sizeof(*dev), mem_startp);
        !           762:                dev->bus = bus;
        !           763:                /*
        !           764:                 * Put it into the simple chain of devices on this
        !           765:                 * bus.  It is used to find devices once everything is
        !           766:                 * set up.
        !           767:                 */
        !           768:                dev->next = pci_devices;
        !           769:                pci_devices = dev;
        !           770: 
        !           771:                dev->devfn  = devfn;
        !           772:                dev->vendor = l & 0xffff;
        !           773:                dev->device = (l >> 16) & 0xffff;
        !           774: 
        !           775:                /*
        !           776:                 * Check to see if we know about this device and report
        !           777:                 * a message at boot time.  This is the only way to
        !           778:                 * learn about new hardware...
        !           779:                 */
        !           780:                info = pci_lookup_dev(dev->vendor, dev->device);
        !           781:                if (!info) {
        !           782:                        printk("Warning : Unknown PCI device (%x:%x).  Please read include/linux/pci.h \n",
        !           783:                                dev->vendor, dev->device);
        !           784:                } else {
        !           785:                        /* Some BIOS' are lazy. Let's do their job: */
        !           786:                        if (info->bridge_type != 0xff) {
        !           787:                                burst_bridge(bus->number, devfn,
        !           788:                                             info->bridge_type, 1);
        !           789:                        }
        !           790:                }
        !           791: 
        !           792:                /* non-destructively determine if device can be a master: */
        !           793:                pcibios_read_config_byte(bus->number, devfn, PCI_COMMAND,
        !           794:                                         &cmd);
        !           795:                pcibios_write_config_byte(bus->number, devfn, PCI_COMMAND,
        !           796:                                          cmd | PCI_COMMAND_MASTER);
        !           797:                pcibios_read_config_byte(bus->number, devfn, PCI_COMMAND,
        !           798:                                         &tmp);
        !           799:                dev->master = ((tmp & PCI_COMMAND_MASTER) != 0);
        !           800:                pcibios_write_config_byte(bus->number, devfn, PCI_COMMAND,
        !           801:                                          cmd);
        !           802: 
        !           803:                /* read irq level (may be changed during pcibios_fixup()): */
        !           804:                pcibios_read_config_byte(bus->number, devfn,
        !           805:                                         PCI_INTERRUPT_LINE, &dev->irq);
        !           806: 
        !           807:                /* check to see if this device is a PCI-PCI bridge: */
        !           808:                pcibios_read_config_dword(bus->number, devfn,
        !           809:                                          PCI_CLASS_REVISION, &l);
        !           810:                l = l >> 8;                     /* upper 3 bytes */
        !           811:                dev->class = l;
        !           812:                /*
        !           813:                 * Now insert it into the list of devices held
        !           814:                 * by the parent bus.
        !           815:                 */
        !           816:                dev->sibling = bus->devices;
        !           817:                bus->devices = dev;
        !           818: 
        !           819:                if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI) {
        !           820:                        unsigned int buses;
        !           821:                        unsigned short cr;
        !           822: 
        !           823:                        /*
        !           824:                         * Insert it into the tree of buses.
        !           825:                         */
        !           826:                        child = pci_malloc(sizeof(*child), mem_startp);
        !           827:                        child->next   = bus->children;
        !           828:                        bus->children = child;
        !           829:                        child->self = dev;
        !           830:                        child->parent = bus;
        !           831: 
        !           832:                        /*
        !           833:                         * Set up the primary, secondary and subordinate
        !           834:                         * bus numbers.
        !           835:                         */
        !           836:                        child->number = child->secondary = ++max;
        !           837:                        child->primary = bus->secondary;
        !           838:                        child->subordinate = 0xff;
        !           839:                        /*
        !           840:                         * Clear all status bits and turn off memory,
        !           841:                         * I/O and master enables.
        !           842:                         */
        !           843:                        pcibios_read_config_word(bus->number, devfn,
        !           844:                                                  PCI_COMMAND, &cr);
        !           845:                        pcibios_write_config_word(bus->number, devfn,
        !           846:                                                  PCI_COMMAND, 0x0000);
        !           847:                        pcibios_write_config_word(bus->number, devfn,
        !           848:                                                  PCI_STATUS, 0xffff);
        !           849:                        /*
        !           850:                         * Configure the bus numbers for this bridge:
        !           851:                         */
        !           852:                        pcibios_read_config_dword(bus->number, devfn, 0x18,
        !           853:                                                  &buses);
        !           854:                        buses &= 0xff000000;
        !           855:                        buses |= (((unsigned int)(child->primary)     <<  0) |
        !           856:                                  ((unsigned int)(child->secondary)   <<  8) |
        !           857:                                  ((unsigned int)(child->subordinate) << 16));
        !           858:                        pcibios_write_config_dword(bus->number, devfn, 0x18,
        !           859:                                                   buses);
        !           860:                        /*
        !           861:                         * Now we can scan all subordinate buses:
        !           862:                         */
        !           863:                        max = scan_bus(child, mem_startp);
        !           864:                        /*
        !           865:                         * Set the subordinate bus number to its real
        !           866:                         * value:
        !           867:                         */
        !           868:                        child->subordinate = max;
        !           869:                        buses = (buses & 0xff00ffff)
        !           870:                          | ((unsigned int)(child->subordinate) << 16);
        !           871:                        pcibios_write_config_dword(bus->number, devfn, 0x18,
        !           872:                                                   buses);
        !           873:                        pcibios_write_config_word(bus->number, devfn,
        !           874:                                                  PCI_COMMAND, cr);
        !           875:                }
        !           876:        }
        !           877:        /*
        !           878:         * We've scanned the bus and so we know all about what's on
        !           879:         * the other side of any bridges that may be on this bus plus
        !           880:         * any devices.
        !           881:         *
        !           882:         * Return how far we've got finding sub-buses.
        !           883:         */
        !           884:        return max;
        !           885: }
        !           886: 
        !           887: 
        !           888: unsigned long pci_init (unsigned long mem_start, unsigned long mem_end)
        !           889: {
        !           890:        mem_start = pcibios_init(mem_start, mem_end);
        !           891: 
        !           892:        if (!pcibios_present()) {
        !           893:                printk("pci_init: no BIOS32 detected\n");
        !           894:                return mem_start;
        !           895:        }
        !           896: 
        !           897: #if 0
        !           898:        printk("Probing PCI hardware.\n");
        !           899: #endif
        !           900: 
        !           901:        memset(&pci_root, 0, sizeof(pci_root));
        !           902:        pci_root.subordinate = scan_bus(&pci_root, &mem_start);
        !           903: 
        !           904:        /* give BIOS a chance to apply platform specific fixes: */
        !           905:        mem_start = pcibios_fixup(mem_start, mem_end);
        !           906: 
        !           907: #ifdef DEBUG
        !           908:        {
        !           909:                int len = get_pci_list((char*)mem_start);
        !           910:                if (len) {
        !           911:                        ((char *) mem_start)[len] = '\0';
        !           912:                        printk("%s\n", (char *) mem_start);
        !           913:                }
        !           914:        }
        !           915: #endif
        !           916:        return mem_start;
        !           917: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.