- Timestamp:
- 04/02/09 21:22:06 (3 years ago)
- Files:
-
- 1 modified
-
Whitix/trunk/devices/pci/pci_core.c (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
Whitix/trunk/devices/pci/pci_core.c
r1925 r2021 24 24 #include <slab.h> 25 25 26 #include <devices/bus.h> 27 26 28 LIST_HEAD(pciBusList); 27 29 struct Cache* pciDeviceCache; … … 106 108 } 107 109 108 char* classes[]=110 static char* classes[]= 109 111 { 110 112 "Unclassified device", … … 128 130 }; 129 131 130 #define PCI_WRITE_TEST 0xFFFFFFFF 131 #define PCI_BAR_BASE 0x10 132 static int PciConvertResFlags(int flags) 133 { 134 if (flags & PCI_RESOURCE_IO) 135 return RESOURCE_IO; 136 137 return RESOURCE_MEM; 138 } 132 139 133 140 int PciDeviceProbe(struct PciDevice* device) … … 140 147 for (i=0; i<6; i++) 141 148 { 149 unsigned long flags; 150 142 151 PciReadConfigDword(device, PCI_BAR_BASE + (i << 2), &v); 143 152 … … 152 161 if (v == PCI_WRITE_TEST) 153 162 v = 0; 163 164 flags = v & 0xF; 165 v &= ~0xF; 154 166 155 167 size &= 0xFFFFFFF0; 156 168 size = (size & ~(size-1)) - 1; 169 157 170 /* 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); 159 174 } 160 175 … … 188 203 deviceId=(WORD)v; 189 204 205 if (vendorId == 0xFFFF && deviceId == 0x0001) 206 { 207 KePrint("TODO: Need to retry read.\n"); 208 } 209 190 210 /* No device here if the vendor ID is invalid. */ 191 211 if (PCI_VENDOR_INVALID(vendorId)) 192 212 return NULL; 193 213 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. */ 196 215 PciRead(bus->index, dev, func, 0x0E, 1, &v); 197 216 deviceType=(BYTE)v; 198 217 199 if (func && !(deviceType & 0x80)) 218 #if 0 219 if (!func && !(deviceType & 0x80)) 200 220 return NULL; 221 #endif 201 222 202 223 /* Allocate the device. */ … … 213 234 device->func=func; 214 235 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 218 243 switch (deviceType & 0x7F) 219 244 { … … 223 248 224 249 case 1: 225 KePrint("PCI to PCI bridge\n");226 250 break; 227 251 … … 229 253 break; 230 254 } 255 256 device->headerType = (deviceType & 0x7F); 231 257 232 258 return device; 233 259 } 260 261 struct 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 269 struct 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 }; 234 278 235 279 int PciScanBus(int index) … … 239 283 struct PciDevice* device; 240 284 285 PreemptDisable(); 286 241 287 /* Allocate the bus. */ 242 288 bus=(struct PciBus*)MemCacheAlloc(pciBusCache); … … 244 290 if (!bus) 245 291 return -ENOMEM; 292 293 KeBusRegister(&pciBusType, &bus->bus, index); 246 294 247 295 INIT_LIST_HEAD(&bus->deviceList); 248 296 ListAddTail(&bus->next, &pciBusList); 249 297 bus->index=index; 298 299 PreemptEnable(); 250 300 251 301 /* Populate its device list. */ … … 253 303 for (func=0; func<8; func++) 254 304 { 255 device =PciProbe(bus, dev, func);305 device = PciProbe(bus, dev, func); 256 306 257 307 if (device) 308 { 258 309 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 } 259 314 } 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? */ 335 int 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 351 void PciLinkDriver(struct PciDevice* device, struct PciDriver* driver) 352 { 353 device->driver = driver; 354 355 IcFsAddSoftLink(device->entry.object.dir, "driver", PciFollowDriverLink); 262 356 } 263 357 … … 275 369 (currId->deviceId == device->deviceId || currId->deviceId == PCI_ID_ANY) && 276 370 (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)) 279 373 { 280 device->driver = driver;281 282 374 /* Matched! Start up the device. */ 283 375 ret = driver->initOne(device, currId); 284 376 285 if ( ret)286 device->driver = NULL;377 if (!ret) 378 PciLinkDriver(device, driver); 287 379 288 380 return ret; … … 298 390 { 299 391 struct PciDevice* curr; 300 392 301 393 ListForEachEntry(curr, &bus->deviceList, next) 302 394 { 303 395 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; 304 402 305 403 ret=PciAttachDriverOne(bus, curr, driver); … … 340 438 int PciInit() 341 439 { 440 struct Thread* thread; 342 441 int type=PciCheckConfig(); 343 442 … … 370 469 } 371 470 372 /* Scan the first bus initially. We may scan other buses as a result. */ 471 KeBusTypeRegister(&pciBusType); 472 373 473 PciScanBus(0); 374 474 375 /* Add devices to IcFs */376 377 475 return 0; 378 476 }
