Changes in uspace/drv/pciintel/pci.c [fb78ae72:ad6857c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/pciintel/pci.c
rfb78ae72 rad6857c 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 44 45 #include <ctype.h> 45 46 #include <macros.h> 46 47 #include <driver.h> 47 #include <str_error.h> 48 49 #include <ddf/driver.h> 48 50 #include <devman.h> 49 51 #include <ipc/devman.h> … … 65 67 ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) 66 68 67 static hw_resource_list_t *pciintel_get_child_resources(device_t *dev) 68 { 69 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 70 71 if (dev_data == NULL) 69 /** Obtain PCI function soft-state from DDF function node */ 70 #define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data) 71 72 /** Obtain PCI bus soft-state from DDF device node */ 73 #define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data) 74 75 /** Obtain PCI bus soft-state from function soft-state */ 76 #define PCI_BUS_FROM_FUN(fun) ((fun)->busptr) 77 78 static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode) 79 { 80 pci_fun_t *fun = PCI_FUN(fnode); 81 82 if (fun == NULL) 72 83 return NULL; 73 return & dev_data->hw_resources;74 } 75 76 static bool pciintel_enable_ child_interrupt(device_t *dev)84 return &fun->hw_resources; 85 } 86 87 static bool pciintel_enable_interrupt(ddf_fun_t *fnode) 77 88 { 78 89 /* This is an old ugly way, copied from ne2000 driver */ 79 assert( dev);80 pci_ dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;90 assert(fnode); 91 pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data; 81 92 82 93 sysarg_t apic; … … 110 121 } 111 122 112 static hw_res_ops_t pciintel_ child_hw_res_ops = {113 &pciintel_get_ child_resources,114 &pciintel_enable_ child_interrupt123 static hw_res_ops_t pciintel_hw_res_ops = { 124 &pciintel_get_resources, 125 &pciintel_enable_interrupt 115 126 }; 116 127 117 static d evice_ops_t pci_child_ops;118 119 static int pci_add_device(d evice_t *);120 121 /** The pci bus driver's standard operations.*/128 static ddf_dev_ops_t pci_fun_ops; 129 130 static int pci_add_device(ddf_dev_t *); 131 132 /** PCI bus driver standard operations */ 122 133 static driver_ops_t pci_ops = { 123 134 .add_device = &pci_add_device 124 135 }; 125 136 126 /** The pci bus driver structure.*/137 /** PCI bus driver structure */ 127 138 static driver_t pci_driver = { 128 139 .name = NAME, … … 130 141 }; 131 142 132 typedef struct pciintel_bus_data { 133 uint32_t conf_io_addr; 134 void *conf_data_port; 135 void *conf_addr_port; 136 fibril_mutex_t conf_mutex; 137 } pci_bus_data_t; 138 139 static pci_bus_data_t *create_pci_bus_data(void) 140 { 141 pci_bus_data_t *bus_data; 142 143 bus_data = (pci_bus_data_t *) malloc(sizeof(pci_bus_data_t)); 144 if (bus_data != NULL) { 145 memset(bus_data, 0, sizeof(pci_bus_data_t)); 146 fibril_mutex_initialize(&bus_data->conf_mutex); 147 } 148 149 return bus_data; 150 } 151 152 static void delete_pci_bus_data(pci_bus_data_t *bus_data) 153 { 154 free(bus_data); 155 } 156 157 static void pci_conf_read(device_t *dev, int reg, uint8_t *buf, size_t len) 158 { 159 assert(dev->parent != NULL); 160 161 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 162 pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data; 163 164 fibril_mutex_lock(&bus_data->conf_mutex); 143 static pci_bus_t *pci_bus_new(void) 144 { 145 pci_bus_t *bus; 146 147 bus = (pci_bus_t *) calloc(1, sizeof(pci_bus_t)); 148 if (bus == NULL) 149 return NULL; 150 151 fibril_mutex_initialize(&bus->conf_mutex); 152 return bus; 153 } 154 155 static void pci_bus_delete(pci_bus_t *bus) 156 { 157 assert(bus != NULL); 158 free(bus); 159 } 160 161 static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 162 { 163 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun); 164 165 fibril_mutex_lock(&bus->conf_mutex); 165 166 166 167 uint32_t conf_addr; 167 conf_addr = CONF_ADDR( dev_data->bus, dev_data->dev, dev_data->fn, reg);168 void *addr = bus _data->conf_data_port + (reg & 3);169 170 pio_write_32(bus _data->conf_addr_port, conf_addr);168 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 169 void *addr = bus->conf_data_port + (reg & 3); 170 171 pio_write_32(bus->conf_addr_port, conf_addr); 171 172 172 173 switch (len) { … … 182 183 } 183 184 184 fibril_mutex_unlock(&bus_data->conf_mutex); 185 } 186 187 static void pci_conf_write(device_t *dev, int reg, uint8_t *buf, size_t len) 188 { 189 assert(dev->parent != NULL); 190 191 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 192 pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data; 193 194 fibril_mutex_lock(&bus_data->conf_mutex); 185 fibril_mutex_unlock(&bus->conf_mutex); 186 } 187 188 static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 189 { 190 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun); 191 192 fibril_mutex_lock(&bus->conf_mutex); 195 193 196 194 uint32_t conf_addr; 197 conf_addr = CONF_ADDR( dev_data->bus, dev_data->dev, dev_data->fn, reg);198 void *addr = bus _data->conf_data_port + (reg & 3);199 200 pio_write_32(bus _data->conf_addr_port, conf_addr);195 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 196 void *addr = bus->conf_data_port + (reg & 3); 197 198 pio_write_32(bus->conf_addr_port, conf_addr); 201 199 202 200 switch (len) { … … 212 210 } 213 211 214 fibril_mutex_unlock(&bus _data->conf_mutex);215 } 216 217 uint8_t pci_conf_read_8( device_t *dev, int reg)212 fibril_mutex_unlock(&bus->conf_mutex); 213 } 214 215 uint8_t pci_conf_read_8(pci_fun_t *fun, int reg) 218 216 { 219 217 uint8_t res; 220 pci_conf_read( dev, reg, &res, 1);218 pci_conf_read(fun, reg, &res, 1); 221 219 return res; 222 220 } 223 221 224 uint16_t pci_conf_read_16( device_t *dev, int reg)222 uint16_t pci_conf_read_16(pci_fun_t *fun, int reg) 225 223 { 226 224 uint16_t res; 227 pci_conf_read( dev, reg, (uint8_t *) &res, 2);225 pci_conf_read(fun, reg, (uint8_t *) &res, 2); 228 226 return res; 229 227 } 230 228 231 uint32_t pci_conf_read_32( device_t *dev, int reg)229 uint32_t pci_conf_read_32(pci_fun_t *fun, int reg) 232 230 { 233 231 uint32_t res; 234 pci_conf_read( dev, reg, (uint8_t *) &res, 4);232 pci_conf_read(fun, reg, (uint8_t *) &res, 4); 235 233 return res; 236 234 } 237 235 238 void pci_conf_write_8(device_t *dev, int reg, uint8_t val) 239 { 240 pci_conf_write(dev, reg, (uint8_t *) &val, 1); 241 } 242 243 void pci_conf_write_16(device_t *dev, int reg, uint16_t val) 244 { 245 pci_conf_write(dev, reg, (uint8_t *) &val, 2); 246 } 247 248 void pci_conf_write_32(device_t *dev, int reg, uint32_t val) 249 { 250 pci_conf_write(dev, reg, (uint8_t *) &val, 4); 251 } 252 253 void create_pci_match_ids(device_t *dev) 254 { 255 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 256 match_id_t *match_id = NULL; 236 void pci_conf_write_8(pci_fun_t *fun, int reg, uint8_t val) 237 { 238 pci_conf_write(fun, reg, (uint8_t *) &val, 1); 239 } 240 241 void pci_conf_write_16(pci_fun_t *fun, int reg, uint16_t val) 242 { 243 pci_conf_write(fun, reg, (uint8_t *) &val, 2); 244 } 245 246 void pci_conf_write_32(pci_fun_t *fun, int reg, uint32_t val) 247 { 248 pci_conf_write(fun, reg, (uint8_t *) &val, 4); 249 } 250 251 void pci_fun_create_match_ids(pci_fun_t *fun) 252 { 257 253 char *match_id_str; 258 259 match_id = create_match_id(); 260 if (match_id != NULL) { 261 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 262 dev_data->vendor_id, dev_data->device_id); 263 match_id->id = match_id_str; 264 match_id->score = 90; 265 add_match_id(&dev->match_ids, match_id); 266 } 267 254 int rc; 255 256 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 257 fun->vendor_id, fun->device_id); 258 259 if (match_id_str == NULL) { 260 printf(NAME ": out of memory creating match ID.\n"); 261 return; 262 } 263 264 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 90); 265 if (rc != EOK) { 266 printf(NAME ": error adding match ID: %s\n", 267 str_error(rc)); 268 } 269 268 270 /* TODO add more ids (with subsys ids, using class id etc.) */ 269 271 } 270 272 271 void 272 pci_add_range(device_t *dev, uint64_t range_addr, size_t range_size, bool io) 273 { 274 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 275 hw_resource_list_t *hw_res_list = &dev_data->hw_resources; 273 void pci_add_range(pci_fun_t *fun, uint64_t range_addr, size_t range_size, 274 bool io) 275 { 276 hw_resource_list_t *hw_res_list = &fun->hw_resources; 276 277 hw_resource_t *hw_resources = hw_res_list->resources; 277 278 size_t count = hw_res_list->count; … … 298 299 * address add it to the devices hw resource list. 299 300 * 300 * @param dev The pci device.301 * @param fun PCI function 301 302 * @param addr The address of the BAR in the PCI configuration address space of 302 * the device .303 * @return The addr the address of the BAR which should be read next .303 * the device 304 * @return The addr the address of the BAR which should be read next 304 305 */ 305 int pci_read_bar( device_t *dev, int addr)306 { 306 int pci_read_bar(pci_fun_t *fun, int addr) 307 { 307 308 /* Value of the BAR */ 308 309 uint32_t val, mask; … … 318 319 319 320 /* Get the value of the BAR. */ 320 val = pci_conf_read_32(dev, addr); 321 val = pci_conf_read_32(fun, addr); 322 323 #define IO_MASK (~0x3) 324 #define MEM_MASK (~0xf) 321 325 322 326 io = (bool) (val & 1); 323 327 if (io) { 324 328 addrw64 = false; 329 mask = IO_MASK; 325 330 } else { 331 mask = MEM_MASK; 326 332 switch ((val >> 1) & 3) { 327 333 case 0: … … 338 344 339 345 /* Get the address mask. */ 340 pci_conf_write_32( dev, addr, 0xffffffff);341 mask = pci_conf_read_32(dev, addr);346 pci_conf_write_32(fun, addr, 0xffffffff); 347 mask &= pci_conf_read_32(fun, addr); 342 348 343 349 /* Restore the original value. */ 344 pci_conf_write_32( dev, addr, val);345 val = pci_conf_read_32( dev, addr);350 pci_conf_write_32(fun, addr, val); 351 val = pci_conf_read_32(fun, addr); 346 352 347 353 range_size = pci_bar_mask_to_size(mask); 348 354 349 355 if (addrw64) { 350 range_addr = ((uint64_t)pci_conf_read_32( dev, addr + 4) << 32) |356 range_addr = ((uint64_t)pci_conf_read_32(fun, addr + 4) << 32) | 351 357 (val & 0xfffffff0); 352 358 } else { … … 355 361 356 362 if (range_addr != 0) { 357 printf(NAME ": device %s : ", dev->name);363 printf(NAME ": function %s : ", fun->fnode->name); 358 364 printf("address = %" PRIx64, range_addr); 359 365 printf(", size = %x\n", (unsigned int) range_size); 360 366 } 361 367 362 pci_add_range( dev, range_addr, range_size, io);368 pci_add_range(fun, range_addr, range_size, io); 363 369 364 370 if (addrw64) … … 368 374 } 369 375 370 void pci_add_interrupt(device_t *dev, int irq) 371 { 372 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 373 hw_resource_list_t *hw_res_list = &dev_data->hw_resources; 376 void pci_add_interrupt(pci_fun_t *fun, int irq) 377 { 378 hw_resource_list_t *hw_res_list = &fun->hw_resources; 374 379 hw_resource_t *hw_resources = hw_res_list->resources; 375 380 size_t count = hw_res_list->count; … … 383 388 hw_res_list->count++; 384 389 385 printf(NAME ": device %s uses irq %x.\n", dev->name, irq);386 } 387 388 void pci_read_interrupt( device_t *dev)389 { 390 uint8_t irq = pci_conf_read_8( dev, PCI_BRIDGE_INT_LINE);390 printf(NAME ": function %s uses irq %x.\n", fun->fnode->name, irq); 391 } 392 393 void pci_read_interrupt(pci_fun_t *fun) 394 { 395 uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE); 391 396 if (irq != 0xff) 392 pci_add_interrupt( dev, irq);397 pci_add_interrupt(fun, irq); 393 398 } 394 399 395 400 /** Enumerate (recursively) and register the devices connected to a pci bus. 396 401 * 397 * @param parent The host-to-pci bridge device.398 * @param bus_num The bus number.402 * @param bus Host-to-PCI bridge 403 * @param bus_num Bus number 399 404 */ 400 void pci_bus_scan(device_t *parent, int bus_num) 401 { 402 device_t *dev = create_device(); 403 pci_dev_data_t *dev_data = create_pci_dev_data(); 404 dev->driver_data = dev_data; 405 dev->parent = parent; 405 void pci_bus_scan(pci_bus_t *bus, int bus_num) 406 { 407 ddf_fun_t *fnode; 408 pci_fun_t *fun; 406 409 407 410 int child_bus = 0; 408 411 int dnum, fnum; 409 412 bool multi; 410 uint8_t header_type; 413 uint8_t header_type; 414 415 fun = pci_fun_new(bus); 411 416 412 417 for (dnum = 0; dnum < 32; dnum++) { 413 418 multi = true; 414 419 for (fnum = 0; multi && fnum < 8; fnum++) { 415 init_pci_dev_data(dev_data, bus_num, dnum, fnum);416 dev_data->vendor_id = pci_conf_read_16(dev,420 pci_fun_init(fun, bus_num, dnum, fnum); 421 fun->vendor_id = pci_conf_read_16(fun, 417 422 PCI_VENDOR_ID); 418 dev_data->device_id = pci_conf_read_16(dev,423 fun->device_id = pci_conf_read_16(fun, 419 424 PCI_DEVICE_ID); 420 if ( dev_data->vendor_id == 0xffff) {425 if (fun->vendor_id == 0xffff) { 421 426 /* 422 427 * The device is not present, go on scanning the … … 429 434 } 430 435 431 header_type = pci_conf_read_8( dev, PCI_HEADER_TYPE);436 header_type = pci_conf_read_8(fun, PCI_HEADER_TYPE); 432 437 if (fnum == 0) { 433 438 /* Is the device multifunction? */ … … 437 442 header_type = header_type & 0x7F; 438 443 439 create_pci_dev_name(dev); 440 441 pci_alloc_resource_list(dev); 442 pci_read_bars(dev); 443 pci_read_interrupt(dev); 444 445 dev->ops = &pci_child_ops; 446 447 printf(NAME ": adding new child device %s.\n", 448 dev->name); 449 450 create_pci_match_ids(dev); 451 452 if (child_device_register(dev, parent) != EOK) { 453 pci_clean_resource_list(dev); 454 clean_match_ids(&dev->match_ids); 455 free((char *) dev->name); 456 dev->name = NULL; 444 char *fun_name = pci_fun_create_name(fun); 445 if (fun_name == NULL) { 446 printf(NAME ": out of memory.\n"); 447 return; 448 } 449 450 fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name); 451 if (fnode == NULL) { 452 printf(NAME ": error creating function.\n"); 453 return; 454 } 455 456 free(fun_name); 457 fun->fnode = fnode; 458 459 pci_alloc_resource_list(fun); 460 pci_read_bars(fun); 461 pci_read_interrupt(fun); 462 463 fnode->ops = &pci_fun_ops; 464 fnode->driver_data = fun; 465 466 printf(NAME ": adding new function %s.\n", 467 fnode->name); 468 469 pci_fun_create_match_ids(fun); 470 471 if (ddf_fun_bind(fnode) != EOK) { 472 pci_clean_resource_list(fun); 473 clean_match_ids(&fnode->match_ids); 474 free((char *) fnode->name); 475 fnode->name = NULL; 457 476 continue; 458 477 } … … 460 479 if (header_type == PCI_HEADER_TYPE_BRIDGE || 461 480 header_type == PCI_HEADER_TYPE_CARDBUS) { 462 child_bus = pci_conf_read_8( dev,481 child_bus = pci_conf_read_8(fun, 463 482 PCI_BRIDGE_SEC_BUS_NUM); 464 483 printf(NAME ": device is pci-to-pci bridge, " 465 484 "secondary bus number = %d.\n", bus_num); 466 485 if (child_bus > bus_num) 467 pci_bus_scan( parent, child_bus);486 pci_bus_scan(bus, child_bus); 468 487 } 469 488 470 /* Alloc new aux. dev. structure. */ 471 dev = create_device(); 472 dev_data = create_pci_dev_data(); 473 dev->driver_data = dev_data; 474 dev->parent = parent; 489 fun = pci_fun_new(bus); 475 490 } 476 491 } 477 492 478 if (dev_data->vendor_id == 0xffff) { 479 delete_device(dev); 480 /* Free the auxiliary device structure. */ 481 delete_pci_dev_data(dev_data); 482 } 483 } 484 485 static int pci_add_device(device_t *dev) 486 { 493 if (fun->vendor_id == 0xffff) { 494 /* Free the auxiliary function structure. */ 495 pci_fun_delete(fun); 496 } 497 } 498 499 static int pci_add_device(ddf_dev_t *dnode) 500 { 501 pci_bus_t *bus = NULL; 502 ddf_fun_t *ctl = NULL; 503 bool got_res = false; 487 504 int rc; 488 505 489 506 printf(NAME ": pci_add_device\n"); 490 491 pci_bus_data_t *bus_data = create_pci_bus_data(); 492 if (bus_data == NULL) { 507 dnode->parent_phone = -1; 508 509 bus = pci_bus_new(); 510 if (bus == NULL) { 493 511 printf(NAME ": pci_add_device allocation failed.\n"); 494 return ENOMEM; 495 } 496 497 dev->parent_phone = devman_parent_device_connect(dev->handle, 512 rc = ENOMEM; 513 goto fail; 514 } 515 bus->dnode = dnode; 516 dnode->driver_data = bus; 517 518 dnode->parent_phone = devman_parent_device_connect(dnode->handle, 498 519 IPC_FLAG_BLOCKING); 499 if (d ev->parent_phone < 0) {520 if (dnode->parent_phone < 0) { 500 521 printf(NAME ": pci_add_device failed to connect to the " 501 522 "parent's driver.\n"); 502 delete_pci_bus_data(bus_data);503 return dev->parent_phone;523 rc = dnode->parent_phone; 524 goto fail; 504 525 } 505 526 506 527 hw_resource_list_t hw_resources; 507 528 508 rc = hw_res_get_resource_list(d ev->parent_phone, &hw_resources);529 rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources); 509 530 if (rc != EOK) { 510 531 printf(NAME ": pci_add_device failed to get hw resources for " 511 532 "the device.\n"); 512 delete_pci_bus_data(bus_data); 513 async_hangup(dev->parent_phone); 514 return rc; 515 } 533 goto fail; 534 } 535 got_res = true; 516 536 517 537 printf(NAME ": conf_addr = %" PRIx64 ".\n", … … 522 542 assert(hw_resources.resources[0].res.io_range.size == 8); 523 543 524 bus _data->conf_io_addr =544 bus->conf_io_addr = 525 545 (uint32_t) hw_resources.resources[0].res.io_range.address; 526 546 527 if (pio_enable((void *)(uintptr_t)bus _data->conf_io_addr, 8,528 &bus _data->conf_addr_port)) {547 if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8, 548 &bus->conf_addr_port)) { 529 549 printf(NAME ": failed to enable configuration ports.\n"); 530 delete_pci_bus_data(bus_data); 531 async_hangup(dev->parent_phone); 550 rc = EADDRNOTAVAIL; 551 goto fail; 552 } 553 bus->conf_data_port = (char *) bus->conf_addr_port + 4; 554 555 /* Make the bus device more visible. It has no use yet. */ 556 printf(NAME ": adding a 'ctl' function\n"); 557 558 ctl = ddf_fun_create(bus->dnode, fun_exposed, "ctl"); 559 if (ctl == NULL) { 560 printf(NAME ": error creating control function.\n"); 561 rc = ENOMEM; 562 goto fail; 563 } 564 565 rc = ddf_fun_bind(ctl); 566 if (rc != EOK) { 567 printf(NAME ": error binding control function.\n"); 568 goto fail; 569 } 570 571 /* Enumerate functions. */ 572 printf(NAME ": scanning the bus\n"); 573 pci_bus_scan(bus, 0); 574 575 hw_res_clean_resource_list(&hw_resources); 576 577 return EOK; 578 579 fail: 580 if (bus != NULL) 581 pci_bus_delete(bus); 582 if (dnode->parent_phone >= 0) 583 async_hangup(dnode->parent_phone); 584 if (got_res) 532 585 hw_res_clean_resource_list(&hw_resources); 533 return EADDRNOTAVAIL; 534 } 535 bus_data->conf_data_port = (char *) bus_data->conf_addr_port + 4; 536 537 dev->driver_data = bus_data; 538 539 /* Enumerate child devices. */ 540 printf(NAME ": scanning the bus\n"); 541 pci_bus_scan(dev, 0); 542 543 hw_res_clean_resource_list(&hw_resources); 544 545 return EOK; 586 if (ctl != NULL) 587 ddf_fun_destroy(ctl); 588 589 return rc; 546 590 } 547 591 548 592 static void pciintel_init(void) 549 593 { 550 pci_child_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_child_hw_res_ops; 551 } 552 553 pci_dev_data_t *create_pci_dev_data(void) 554 { 555 pci_dev_data_t *res = (pci_dev_data_t *) malloc(sizeof(pci_dev_data_t)); 556 557 if (res != NULL) 558 memset(res, 0, sizeof(pci_dev_data_t)); 559 return res; 560 } 561 562 void init_pci_dev_data(pci_dev_data_t *dev_data, int bus, int dev, int fn) 563 { 564 dev_data->bus = bus; 565 dev_data->dev = dev; 566 dev_data->fn = fn; 567 } 568 569 void delete_pci_dev_data(pci_dev_data_t *dev_data) 570 { 571 if (dev_data != NULL) { 572 hw_res_clean_resource_list(&dev_data->hw_resources); 573 free(dev_data); 574 } 575 } 576 577 void create_pci_dev_name(device_t *dev) 578 { 579 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 594 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 595 } 596 597 pci_fun_t *pci_fun_new(pci_bus_t *bus) 598 { 599 pci_fun_t *fun; 600 601 fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t)); 602 if (fun == NULL) 603 return NULL; 604 605 fun->busptr = bus; 606 return fun; 607 } 608 609 void pci_fun_init(pci_fun_t *fun, int bus, int dev, int fn) 610 { 611 fun->bus = bus; 612 fun->dev = dev; 613 fun->fn = fn; 614 } 615 616 void pci_fun_delete(pci_fun_t *fun) 617 { 618 assert(fun != NULL); 619 hw_res_clean_resource_list(&fun->hw_resources); 620 free(fun); 621 } 622 623 char *pci_fun_create_name(pci_fun_t *fun) 624 { 580 625 char *name = NULL; 581 626 582 asprintf(&name, "%02x:%02x.%01x", dev_data->bus, dev_data->dev, 583 dev_data->fn); 584 dev->name = name; 585 } 586 587 bool pci_alloc_resource_list(device_t *dev) 588 { 589 pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data; 590 591 dev_data->hw_resources.resources = 627 asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev, 628 fun->fn); 629 return name; 630 } 631 632 bool pci_alloc_resource_list(pci_fun_t *fun) 633 { 634 fun->hw_resources.resources = 592 635 (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t)); 593 return dev_data->hw_resources.resources != NULL; 594 } 595 596 void pci_clean_resource_list(device_t *dev) 597 { 598 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 599 600 if (dev_data->hw_resources.resources != NULL) { 601 free(dev_data->hw_resources.resources); 602 dev_data->hw_resources.resources = NULL; 603 } 604 } 605 606 /** Read the base address registers (BARs) of the device and adds the addresses 607 * to its hw resource list. 636 return fun->hw_resources.resources != NULL; 637 } 638 639 void pci_clean_resource_list(pci_fun_t *fun) 640 { 641 if (fun->hw_resources.resources != NULL) { 642 free(fun->hw_resources.resources); 643 fun->hw_resources.resources = NULL; 644 } 645 } 646 647 /** Read the base address registers (BARs) of the function and add the addresses 648 * to its HW resource list. 608 649 * 609 * @param dev the pci device.650 * @param fun PCI function 610 651 */ 611 void pci_read_bars( device_t *dev)652 void pci_read_bars(pci_fun_t *fun) 612 653 { 613 654 /* … … 618 659 619 660 while (addr <= PCI_BASE_ADDR_5) 620 addr = pci_read_bar( dev, addr);661 addr = pci_read_bar(fun, addr); 621 662 } 622 663 623 664 size_t pci_bar_mask_to_size(uint32_t mask) 624 665 { 625 return ((mask & 0xfffffff0) ^ 0xffffffff) + 1; 666 size_t size = mask & ~(mask - 1); 667 return size; 626 668 } 627 669 … … 630 672 printf(NAME ": HelenOS pci bus driver (intel method 1).\n"); 631 673 pciintel_init(); 632 return d river_main(&pci_driver);674 return ddf_driver_main(&pci_driver); 633 675 } 634 676
Note:
See TracChangeset
for help on using the changeset viewer.