Changeset 8b1e15ac in mainline for uspace/drv/pciintel/pci.c
- Timestamp:
- 2011-02-11T22:26:36Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 68414f4a
- Parents:
- 1b367b4
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/pciintel/pci.c
r1b367b4 r8b1e15ac 61 61 ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) 62 62 63 static hw_resource_list_t *pciintel_get_child_resources( device_t *dev)64 { 65 pci_ dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;66 67 if ( dev_data == NULL)63 static hw_resource_list_t *pciintel_get_child_resources(function_t *fun) 64 { 65 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 66 67 if (fun_data == NULL) 68 68 return NULL; 69 return & dev_data->hw_resources;70 } 71 72 static bool pciintel_enable_child_interrupt( device_t *dev)69 return &fun_data->hw_resources; 70 } 71 72 static bool pciintel_enable_child_interrupt(function_t *fun) 73 73 { 74 74 /* TODO */ … … 122 122 } 123 123 124 static void pci_conf_read( device_t *dev, int reg, uint8_t *buf, size_t len)125 { 126 assert( dev->parent!= NULL);127 128 pci_ dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;129 pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data;124 static void pci_conf_read(function_t *fun, int reg, uint8_t *buf, size_t len) 125 { 126 assert(fun->dev != NULL); 127 128 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 129 pci_bus_data_t *bus_data = (pci_bus_data_t *) fun->dev->driver_data; 130 130 131 131 fibril_mutex_lock(&bus_data->conf_mutex); 132 132 133 133 uint32_t conf_addr; 134 conf_addr = CONF_ADDR( dev_data->bus, dev_data->dev, dev_data->fn, reg);134 conf_addr = CONF_ADDR(fun_data->bus, fun_data->dev, fun_data->fn, reg); 135 135 void *addr = bus_data->conf_data_port + (reg & 3); 136 136 … … 152 152 } 153 153 154 static void pci_conf_write( device_t *dev, int reg, uint8_t *buf, size_t len)155 { 156 assert( dev->parent!= NULL);157 158 pci_ dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;159 pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data;154 static void pci_conf_write(function_t *fun, int reg, uint8_t *buf, size_t len) 155 { 156 assert(fun->dev != NULL); 157 158 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 159 pci_bus_data_t *bus_data = (pci_bus_data_t *) fun->dev->driver_data; 160 160 161 161 fibril_mutex_lock(&bus_data->conf_mutex); 162 162 163 163 uint32_t conf_addr; 164 conf_addr = CONF_ADDR( dev_data->bus, dev_data->dev, dev_data->fn, reg);164 conf_addr = CONF_ADDR(fun_data->bus, fun_data->dev, fun_data->fn, reg); 165 165 void *addr = bus_data->conf_data_port + (reg & 3); 166 166 … … 182 182 } 183 183 184 uint8_t pci_conf_read_8( device_t *dev, int reg)184 uint8_t pci_conf_read_8(function_t *fun, int reg) 185 185 { 186 186 uint8_t res; 187 pci_conf_read( dev, reg, &res, 1);187 pci_conf_read(fun, reg, &res, 1); 188 188 return res; 189 189 } 190 190 191 uint16_t pci_conf_read_16( device_t *dev, int reg)191 uint16_t pci_conf_read_16(function_t *fun, int reg) 192 192 { 193 193 uint16_t res; 194 pci_conf_read( dev, reg, (uint8_t *) &res, 2);194 pci_conf_read(fun, reg, (uint8_t *) &res, 2); 195 195 return res; 196 196 } 197 197 198 uint32_t pci_conf_read_32( device_t *dev, int reg)198 uint32_t pci_conf_read_32(function_t *fun, int reg) 199 199 { 200 200 uint32_t res; 201 pci_conf_read( dev, reg, (uint8_t *) &res, 4);201 pci_conf_read(fun, reg, (uint8_t *) &res, 4); 202 202 return res; 203 203 } 204 204 205 void pci_conf_write_8( device_t *dev, int reg, uint8_t val)206 { 207 pci_conf_write( dev, reg, (uint8_t *) &val, 1);208 } 209 210 void pci_conf_write_16( device_t *dev, int reg, uint16_t val)211 { 212 pci_conf_write( dev, reg, (uint8_t *) &val, 2);213 } 214 215 void pci_conf_write_32( device_t *dev, int reg, uint32_t val)216 { 217 pci_conf_write( dev, reg, (uint8_t *) &val, 4);218 } 219 220 void create_pci_match_ids( device_t *dev)221 { 222 pci_ dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;205 void pci_conf_write_8(function_t *fun, int reg, uint8_t val) 206 { 207 pci_conf_write(fun, reg, (uint8_t *) &val, 1); 208 } 209 210 void pci_conf_write_16(function_t *fun, int reg, uint16_t val) 211 { 212 pci_conf_write(fun, reg, (uint8_t *) &val, 2); 213 } 214 215 void pci_conf_write_32(function_t *fun, int reg, uint32_t val) 216 { 217 pci_conf_write(fun, reg, (uint8_t *) &val, 4); 218 } 219 220 void create_pci_match_ids(function_t *fun) 221 { 222 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 223 223 match_id_t *match_id = NULL; 224 224 char *match_id_str; … … 227 227 if (match_id != NULL) { 228 228 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 229 dev_data->vendor_id, dev_data->device_id);229 fun_data->vendor_id, fun_data->device_id); 230 230 match_id->id = match_id_str; 231 231 match_id->score = 90; 232 add_match_id(& dev->match_ids, match_id);232 add_match_id(&fun->match_ids, match_id); 233 233 } 234 234 … … 237 237 238 238 void 239 pci_add_range( device_t *dev, uint64_t range_addr, size_t range_size, bool io)240 { 241 pci_ dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;242 hw_resource_list_t *hw_res_list = & dev_data->hw_resources;239 pci_add_range(function_t *fun, uint64_t range_addr, size_t range_size, bool io) 240 { 241 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 242 hw_resource_list_t *hw_res_list = &fun_data->hw_resources; 243 243 hw_resource_t *hw_resources = hw_res_list->resources; 244 244 size_t count = hw_res_list->count; … … 270 270 * @return The addr the address of the BAR which should be read next. 271 271 */ 272 int pci_read_bar( device_t *dev, int addr)272 int pci_read_bar(function_t *fun, int addr) 273 273 { 274 274 /* Value of the BAR */ … … 285 285 286 286 /* Get the value of the BAR. */ 287 val = pci_conf_read_32( dev, addr);287 val = pci_conf_read_32(fun, addr); 288 288 289 289 io = (bool) (val & 1); … … 305 305 306 306 /* Get the address mask. */ 307 pci_conf_write_32( dev, addr, 0xffffffff);308 mask = pci_conf_read_32( dev, addr);307 pci_conf_write_32(fun, addr, 0xffffffff); 308 mask = pci_conf_read_32(fun, addr); 309 309 310 310 /* Restore the original value. */ 311 pci_conf_write_32( dev, addr, val);312 val = pci_conf_read_32( dev, addr);311 pci_conf_write_32(fun, addr, val); 312 val = pci_conf_read_32(fun, addr); 313 313 314 314 range_size = pci_bar_mask_to_size(mask); 315 315 316 316 if (addrw64) { 317 range_addr = ((uint64_t)pci_conf_read_32( dev, addr + 4) << 32) |317 range_addr = ((uint64_t)pci_conf_read_32(fun, addr + 4) << 32) | 318 318 (val & 0xfffffff0); 319 319 } else { … … 322 322 323 323 if (range_addr != 0) { 324 printf(NAME ": device %s : ", dev->name);324 printf(NAME ": function %s : ", fun->name); 325 325 printf("address = %" PRIx64, range_addr); 326 326 printf(", size = %x\n", (unsigned int) range_size); 327 327 } 328 328 329 pci_add_range( dev, range_addr, range_size, io);329 pci_add_range(fun, range_addr, range_size, io); 330 330 331 331 if (addrw64) … … 335 335 } 336 336 337 void pci_add_interrupt( device_t *dev, int irq)338 { 339 pci_ dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;340 hw_resource_list_t *hw_res_list = & dev_data->hw_resources;337 void pci_add_interrupt(function_t *fun, int irq) 338 { 339 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 340 hw_resource_list_t *hw_res_list = &fun_data->hw_resources; 341 341 hw_resource_t *hw_resources = hw_res_list->resources; 342 342 size_t count = hw_res_list->count; … … 350 350 hw_res_list->count++; 351 351 352 printf(NAME ": device %s uses irq %x.\n", dev->name, irq);353 } 354 355 void pci_read_interrupt( device_t *dev)356 { 357 uint8_t irq = pci_conf_read_8( dev, PCI_BRIDGE_INT_LINE);352 printf(NAME ": function %s uses irq %x.\n", fun->name, irq); 353 } 354 355 void pci_read_interrupt(function_t *fun) 356 { 357 uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE); 358 358 if (irq != 0xff) 359 pci_add_interrupt( dev, irq);359 pci_add_interrupt(fun, irq); 360 360 } 361 361 362 362 /** Enumerate (recursively) and register the devices connected to a pci bus. 363 363 * 364 * @param parentThe host-to-pci bridge device.364 * @param dev The host-to-pci bridge device. 365 365 * @param bus_num The bus number. 366 366 */ 367 void pci_bus_scan(device_t *parent, int bus_num) 368 { 369 device_t *dev = create_device(); 370 pci_dev_data_t *dev_data = create_pci_dev_data(); 371 dev->driver_data = dev_data; 372 dev->parent = parent; 367 void pci_bus_scan(device_t *dev, int bus_num) 368 { 369 function_t *fun = create_function(); 370 pci_fun_data_t *fun_data = create_pci_fun_data(); 371 fun->driver_data = fun_data; 373 372 374 373 int child_bus = 0; 375 374 int dnum, fnum; 376 375 bool multi; 377 uint8_t header_type; 376 uint8_t header_type; 377 378 /* We need this early, before registering. */ 379 fun->dev = dev; 378 380 379 381 for (dnum = 0; dnum < 32; dnum++) { 380 382 multi = true; 381 383 for (fnum = 0; multi && fnum < 8; fnum++) { 382 init_pci_ dev_data(dev_data, bus_num, dnum, fnum);383 dev_data->vendor_id = pci_conf_read_16(dev,384 init_pci_fun_data(fun_data, bus_num, dnum, fnum); 385 fun_data->vendor_id = pci_conf_read_16(fun, 384 386 PCI_VENDOR_ID); 385 dev_data->device_id = pci_conf_read_16(dev,387 fun_data->device_id = pci_conf_read_16(fun, 386 388 PCI_DEVICE_ID); 387 if ( dev_data->vendor_id == 0xffff) {389 if (fun_data->vendor_id == 0xffff) { 388 390 /* 389 391 * The device is not present, go on scanning the … … 396 398 } 397 399 398 header_type = pci_conf_read_8( dev, PCI_HEADER_TYPE);400 header_type = pci_conf_read_8(fun, PCI_HEADER_TYPE); 399 401 if (fnum == 0) { 400 402 /* Is the device multifunction? */ … … 404 406 header_type = header_type & 0x7F; 405 407 406 create_pci_dev_name(dev); 407 408 pci_alloc_resource_list(dev); 409 pci_read_bars(dev); 410 pci_read_interrupt(dev); 411 412 dev->ops = &pci_child_ops; 413 414 printf(NAME ": adding new child device %s.\n", 415 dev->name); 416 417 create_pci_match_ids(dev); 418 419 if (child_device_register(dev, parent) != EOK) { 420 pci_clean_resource_list(dev); 421 clean_match_ids(&dev->match_ids); 422 free((char *) dev->name); 423 dev->name = NULL; 408 create_pci_fun_name(fun); 409 410 pci_alloc_resource_list(fun); 411 pci_read_bars(fun); 412 pci_read_interrupt(fun); 413 414 fun->ftype = fun_inner; 415 fun->ops = &pci_child_ops; 416 417 printf(NAME ": adding new function %s.\n", 418 fun->name); 419 420 create_pci_match_ids(fun); 421 422 if (register_function(fun, dev) != EOK) { 423 pci_clean_resource_list(fun); 424 clean_match_ids(&fun->match_ids); 425 free((char *) fun->name); 426 fun->name = NULL; 424 427 continue; 425 428 } … … 427 430 if (header_type == PCI_HEADER_TYPE_BRIDGE || 428 431 header_type == PCI_HEADER_TYPE_CARDBUS) { 429 child_bus = pci_conf_read_8( dev,432 child_bus = pci_conf_read_8(fun, 430 433 PCI_BRIDGE_SEC_BUS_NUM); 431 434 printf(NAME ": device is pci-to-pci bridge, " 432 435 "secondary bus number = %d.\n", bus_num); 433 436 if (child_bus > bus_num) 434 pci_bus_scan( parent, child_bus);437 pci_bus_scan(dev, child_bus); 435 438 } 436 439 437 /* Alloc new aux. dev. structure. */ 438 dev = create_device(); 439 dev_data = create_pci_dev_data(); 440 dev->driver_data = dev_data; 441 dev->parent = parent; 440 /* Alloc new aux. fun. structure. */ 441 fun = create_function(); 442 443 /* We need this early, before registering. */ 444 fun->dev = dev; 445 446 fun_data = create_pci_fun_data(); 447 fun->driver_data = fun_data; 442 448 } 443 449 } 444 450 445 if ( dev_data->vendor_id == 0xffff) {446 delete_ device(dev);447 /* Free the auxiliary devicestructure. */448 delete_pci_ dev_data(dev_data);451 if (fun_data->vendor_id == 0xffff) { 452 delete_function(fun); 453 /* Free the auxiliary function structure. */ 454 delete_pci_fun_data(fun_data); 449 455 } 450 456 } … … 504 510 dev->driver_data = bus_data; 505 511 512 /* Make the bus device more visible. Does not do anything. */ 513 printf(NAME ": adding a 'ctl' function\n"); 514 515 function_t *ctl = create_function(); 516 ctl->ftype = fun_exposed; 517 ctl->name = "ctl"; 518 register_function(ctl, dev); 519 506 520 /* Enumerate child devices. */ 507 521 printf(NAME ": scanning the bus\n"); … … 518 532 } 519 533 520 pci_ dev_data_t *create_pci_dev_data(void)521 { 522 pci_ dev_data_t *res = (pci_dev_data_t *) malloc(sizeof(pci_dev_data_t));534 pci_fun_data_t *create_pci_fun_data(void) 535 { 536 pci_fun_data_t *res = (pci_fun_data_t *) malloc(sizeof(pci_fun_data_t)); 523 537 524 538 if (res != NULL) 525 memset(res, 0, sizeof(pci_ dev_data_t));539 memset(res, 0, sizeof(pci_fun_data_t)); 526 540 return res; 527 541 } 528 542 529 void init_pci_ dev_data(pci_dev_data_t *dev_data, int bus, int dev, int fn)530 { 531 dev_data->bus = bus;532 dev_data->dev = dev;533 dev_data->fn = fn;534 } 535 536 void delete_pci_ dev_data(pci_dev_data_t *dev_data)537 { 538 if ( dev_data != NULL) {539 hw_res_clean_resource_list(& dev_data->hw_resources);540 free( dev_data);541 } 542 } 543 544 void create_pci_ dev_name(device_t *dev)545 { 546 pci_ dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;543 void init_pci_fun_data(pci_fun_data_t *fun_data, int bus, int dev, int fn) 544 { 545 fun_data->bus = bus; 546 fun_data->dev = dev; 547 fun_data->fn = fn; 548 } 549 550 void delete_pci_fun_data(pci_fun_data_t *fun_data) 551 { 552 if (fun_data != NULL) { 553 hw_res_clean_resource_list(&fun_data->hw_resources); 554 free(fun_data); 555 } 556 } 557 558 void create_pci_fun_name(function_t *fun) 559 { 560 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 547 561 char *name = NULL; 548 562 549 asprintf(&name, "%02x:%02x.%01x", dev_data->bus, dev_data->dev,550 dev_data->fn);551 dev->name = name;552 } 553 554 bool pci_alloc_resource_list( device_t *dev)555 { 556 pci_ dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data;557 558 dev_data->hw_resources.resources =563 asprintf(&name, "%02x:%02x.%01x", fun_data->bus, fun_data->dev, 564 fun_data->fn); 565 fun->name = name; 566 } 567 568 bool pci_alloc_resource_list(function_t *fun) 569 { 570 pci_fun_data_t *fun_data = (pci_fun_data_t *)fun->driver_data; 571 572 fun_data->hw_resources.resources = 559 573 (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t)); 560 return dev_data->hw_resources.resources != NULL;561 } 562 563 void pci_clean_resource_list( device_t *dev)564 { 565 pci_ dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;566 567 if ( dev_data->hw_resources.resources != NULL) {568 free( dev_data->hw_resources.resources);569 dev_data->hw_resources.resources = NULL;574 return fun_data->hw_resources.resources != NULL; 575 } 576 577 void pci_clean_resource_list(function_t *fun) 578 { 579 pci_fun_data_t *fun_data = (pci_fun_data_t *) fun->driver_data; 580 581 if (fun_data->hw_resources.resources != NULL) { 582 free(fun_data->hw_resources.resources); 583 fun_data->hw_resources.resources = NULL; 570 584 } 571 585 } … … 576 590 * @param dev the pci device. 577 591 */ 578 void pci_read_bars( device_t *dev)592 void pci_read_bars(function_t *fun) 579 593 { 580 594 /* … … 585 599 586 600 while (addr <= PCI_BASE_ADDR_5) 587 addr = pci_read_bar( dev, addr);601 addr = pci_read_bar(fun, addr); 588 602 } 589 603
Note:
See TracChangeset
for help on using the changeset viewer.