Changeset 2021 for Whitix

Show
Ignore:
Timestamp:
04/02/09 21:22:06 (3 years ago)
Author:
mwhitworth
Message:

Register PCI as a bus type, add attributes, fix PCI resource detection code.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • Whitix/trunk/devices/pci/pci_core.c

    r1925 r2021  
    2424#include <slab.h> 
    2525 
     26#include <devices/bus.h> 
     27 
    2628LIST_HEAD(pciBusList); 
    2729struct Cache* pciDeviceCache; 
     
    106108} 
    107109 
    108 char* classes[]= 
     110static char* classes[]= 
    109111{ 
    110112        "Unclassified device", 
     
    128130}; 
    129131 
    130 #define PCI_WRITE_TEST  0xFFFFFFFF 
    131 #define PCI_BAR_BASE    0x10 
     132static int PciConvertResFlags(int flags) 
     133{ 
     134        if (flags & PCI_RESOURCE_IO) 
     135                return RESOURCE_IO; 
     136                 
     137        return RESOURCE_MEM; 
     138} 
    132139 
    133140int PciDeviceProbe(struct PciDevice* device) 
     
    140147        for (i=0; i<6; i++) 
    141148        { 
     149                unsigned long flags; 
     150                 
    142151                PciReadConfigDword(device, PCI_BAR_BASE + (i << 2), &v); 
    143152         
     
    152161                if (v == PCI_WRITE_TEST) 
    153162                        v = 0; 
     163                         
     164                flags = v & 0xF; 
     165                v &= ~0xF; 
    154166                 
    155167                size &= 0xFFFFFFF0; 
    156                                                          
     168                size = (size & ~(size-1)) - 1; 
     169                                                                                                                 
    157170                /* Parse the base address register. */ 
    158                 device->spaces[i] = v; 
     171                device->spaces[i].start = v; 
     172                device->spaces[i].len = size; 
     173                device->spaces[i].flags = PciConvertResFlags(flags); 
    159174        } 
    160175 
     
    188203        deviceId=(WORD)v; 
    189204 
     205        if (vendorId == 0xFFFF && deviceId == 0x0001) 
     206        { 
     207                KePrint("TODO: Need to retry read.\n"); 
     208        } 
     209 
    190210        /* No device here if the vendor ID is invalid. */ 
    191211        if (PCI_VENDOR_INVALID(vendorId)) 
    192212                return NULL; 
    193213 
    194         /* Read in the header type to find out if it is a multi-function device. 
    195          * If it isn't, there's no point allocating a device structure for it. */ 
     214        /* Read in the header type to find out if it is a multi-function device. */ 
    196215        PciRead(bus->index, dev, func, 0x0E, 1, &v); 
    197216        deviceType=(BYTE)v; 
    198217 
    199         if (func && !(deviceType & 0x80)) 
     218#if 0 
     219        if (!func && !(deviceType & 0x80)) 
    200220                return NULL; 
     221#endif 
    201222 
    202223        /* Allocate the device. */ 
     
    213234        device->func=func; 
    214235 
    215         PciReadConfigByte(device, 0x0B, &device->devClass); 
    216         PciReadConfigByte(device, 0x0A, &device->subClass); 
    217          
     236        /* Once we have the basic device information set up, we can use the 
     237         * PciReadConfig* functions. */ 
     238        PciReadConfigDword(device, 0x08, &device->devClass); 
     239         
     240        /* Shift out the revision id. */ 
     241        device->devClass >>= 8; 
     242                 
    218243        switch (deviceType & 0x7F) 
    219244        { 
     
    223248 
    224249                case 1: 
    225                         KePrint("PCI to PCI bridge\n"); 
    226250                        break; 
    227251 
     
    229253                        break; 
    230254        } 
     255         
     256        device->headerType = (deviceType & 0x7F); 
    231257 
    232258        return device; 
    233259} 
     260 
     261struct IcAttribute pciBusAttrs[] = 
     262{ 
     263        IC_INT(struct PciDevice, vendorId, IC_READ), 
     264        IC_INT(struct PciDevice, deviceId, IC_READ), 
     265        IC_INT(struct PciDevice, devClass, IC_READ), 
     266        IC_END(), 
     267}; 
     268 
     269struct KeBusType pciBusType= 
     270{ 
     271        .name = "Pci", 
     272//      .match = PciDeviceMatch, 
     273 
     274        /* Used when adding a bus entry. */ 
     275        .busEntryAttrs = pciBusAttrs, 
     276        .busEntryOffset = OffsetOf(struct PciDevice, entry), 
     277}; 
    234278 
    235279int PciScanBus(int index) 
     
    239283        struct PciDevice* device; 
    240284 
     285        PreemptDisable(); 
     286 
    241287        /* Allocate the bus. */ 
    242288        bus=(struct PciBus*)MemCacheAlloc(pciBusCache); 
     
    244290        if (!bus) 
    245291                return -ENOMEM; 
     292 
     293        KeBusRegister(&pciBusType, &bus->bus, index); 
    246294 
    247295        INIT_LIST_HEAD(&bus->deviceList); 
    248296        ListAddTail(&bus->next, &pciBusList); 
    249297        bus->index=index; 
     298 
     299        PreemptEnable(); 
    250300 
    251301        /* Populate its device list. */ 
     
    253303                for (func=0; func<8; func++) 
    254304                { 
    255                         device=PciProbe(bus, dev, func); 
     305                        device = PciProbe(bus, dev, func); 
    256306 
    257307                        if (device) 
     308                        { 
    258309                                ListAddTail(&device->next, &bus->deviceList); 
     310                                 
     311                                /* FIXME: Create and register device, add to bus list of devices. */ 
     312                                KeBusEntryRegister(&bus->bus, &device->entry, "%d.%d", dev, func); 
     313                        } 
    259314                } 
    260  
    261         return 0; 
     315                 
     316        /* Scan all the child bridges. */ 
     317        ListForEachEntry(device, &bus->deviceList, next) 
     318        { 
     319                if (device->headerType == 1) 
     320                { 
     321                        DWORD bus; 
     322                         
     323                        PciReadConfigDword(device, PCI_PRIMARY_BUS, &bus); 
     324                                                                         
     325                        //PciScanBus(busNumber); 
     326                } 
     327        } 
     328                 
     329        KeBusStart(&bus->bus); 
     330 
     331        return 0; 
     332} 
     333 
     334/* FIXME: Need to get KeObject from IcFs? */     
     335int PciFollowDriverLink(struct KeFsEntry** dest, struct KeFsEntry* src) 
     336{ 
     337        struct KeObject* object = NULL; /* Doesn't work. */ 
     338        struct KeBusEntry* entry = ContainerOf(object, struct KeBusEntry, object); 
     339        struct PciDevice* device = ContainerOf(entry, struct PciDevice, entry); 
     340                 
     341        /* If this is true, the symbolic link should not have been created in the 
     342         * first place. */ 
     343        if (!device->driver || !device->driver->module) 
     344                return -ENOENT; 
     345                 
     346        *dest = ModuleGetIcDir(device->driver->module); 
     347         
     348        return 0; 
     349} 
     350 
     351void PciLinkDriver(struct PciDevice* device, struct PciDriver* driver) 
     352{ 
     353        device->driver = driver; 
     354         
     355        IcFsAddSoftLink(device->entry.object.dir, "driver", PciFollowDriverLink); 
    262356} 
    263357 
     
    275369                        (currId->deviceId == device->deviceId || currId->deviceId == PCI_ID_ANY) && 
    276370                        (currId->subVendor == device->subVendor || currId->subVendor == PCI_ID_ANY) && 
    277                         (currId->subDevice == device->subDevice || currId->subDevice == PCI_ID_ANY) /*&& 
    278                         ((currId->class ^ device->devClass) & currId->classMask)*/) 
     371                        (currId->subDevice == device->subDevice || currId->subDevice == PCI_ID_ANY) && 
     372                        !((currId->class ^ device->devClass) & currId->classMask)) 
    279373                { 
    280                         device->driver = driver; 
    281                          
    282374                        /* Matched! Start up the device. */ 
    283375                        ret = driver->initOne(device, currId); 
    284376                         
    285                         if (ret) 
    286                                 device->driver = NULL; 
     377                        if (!ret) 
     378                                PciLinkDriver(device, driver); 
    287379                                 
    288380                        return ret; 
     
    298390{ 
    299391        struct PciDevice* curr; 
    300  
     392                 
    301393        ListForEachEntry(curr, &bus->deviceList, next) 
    302394        { 
    303395                int ret; 
     396                 
     397                /* If we've already attached a driver to this device, don't bother 
     398                 * scanning it again. 
     399                 */ 
     400                if (curr->driver) 
     401                        continue; 
    304402 
    305403                ret=PciAttachDriverOne(bus, curr, driver); 
     
    340438int PciInit() 
    341439{ 
     440        struct Thread* thread; 
    342441        int type=PciCheckConfig();       
    343442 
     
    370469        } 
    371470 
    372         /* Scan the first bus initially. We may scan other buses as a result. */ 
     471        KeBusTypeRegister(&pciBusType); 
     472         
    373473        PciScanBus(0); 
    374474 
    375         /* Add devices to IcFs */ 
    376  
    377475        return 0; 
    378476}