Changeset ad7a6c9 in mainline for uspace/drv/pciintel/pci.c
- Timestamp:
- 2011-03-30T13:10:24Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4ae90f9
- Parents:
- 6e50466 (diff), d6b81941 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/pciintel/pci.c
r6e50466 rad7a6c9 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> 50 52 #include <ipc/dev_iface.h> 51 #include < resource.h>53 #include <ops/hw_res.h> 52 54 #include <device/hw_res.h> 53 55 #include <ddi.h> … … 61 63 ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) 62 64 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) 65 /** Obtain PCI function soft-state from DDF function node */ 66 #define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data) 67 68 /** Obtain PCI bus soft-state from DDF device node */ 69 #define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data) 70 71 /** Obtain PCI bus soft-state from function soft-state */ 72 #define PCI_BUS_FROM_FUN(fun) ((fun)->busptr) 73 74 static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode) 75 { 76 pci_fun_t *fun = PCI_FUN(fnode); 77 78 if (fun == NULL) 68 79 return NULL; 69 return & dev_data->hw_resources;70 } 71 72 static bool pciintel_enable_ child_interrupt(device_t *dev)80 return &fun->hw_resources; 81 } 82 83 static bool pciintel_enable_interrupt(ddf_fun_t *fnode) 73 84 { 74 85 /* TODO */ … … 77 88 } 78 89 79 static resource_iface_t pciintel_child_res_iface= {80 &pciintel_get_ child_resources,81 &pciintel_enable_ child_interrupt90 static hw_res_ops_t pciintel_hw_res_ops = { 91 &pciintel_get_resources, 92 &pciintel_enable_interrupt 82 93 }; 83 94 84 static d evice_ops_t pci_child_ops;85 86 static int pci_add_device(d evice_t *);87 88 /** The pci bus driver's standard operations.*/95 static ddf_dev_ops_t pci_fun_ops; 96 97 static int pci_add_device(ddf_dev_t *); 98 99 /** PCI bus driver standard operations */ 89 100 static driver_ops_t pci_ops = { 90 101 .add_device = &pci_add_device 91 102 }; 92 103 93 /** The pci bus driver structure.*/104 /** PCI bus driver structure */ 94 105 static driver_t pci_driver = { 95 106 .name = NAME, … … 97 108 }; 98 109 99 typedef struct pciintel_bus_data { 100 uint32_t conf_io_addr; 101 void *conf_data_port; 102 void *conf_addr_port; 103 fibril_mutex_t conf_mutex; 104 } pci_bus_data_t; 105 106 static pci_bus_data_t *create_pci_bus_data(void) 107 { 108 pci_bus_data_t *bus_data; 109 110 bus_data = (pci_bus_data_t *) malloc(sizeof(pci_bus_data_t)); 111 if (bus_data != NULL) { 112 memset(bus_data, 0, sizeof(pci_bus_data_t)); 113 fibril_mutex_initialize(&bus_data->conf_mutex); 114 } 115 116 return bus_data; 117 } 118 119 static void delete_pci_bus_data(pci_bus_data_t *bus_data) 120 { 121 free(bus_data); 122 } 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; 130 131 fibril_mutex_lock(&bus_data->conf_mutex); 110 static pci_bus_t *pci_bus_new(void) 111 { 112 pci_bus_t *bus; 113 114 bus = (pci_bus_t *) calloc(1, sizeof(pci_bus_t)); 115 if (bus == NULL) 116 return NULL; 117 118 fibril_mutex_initialize(&bus->conf_mutex); 119 return bus; 120 } 121 122 static void pci_bus_delete(pci_bus_t *bus) 123 { 124 assert(bus != NULL); 125 free(bus); 126 } 127 128 static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 129 { 130 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun); 131 132 fibril_mutex_lock(&bus->conf_mutex); 132 133 133 134 uint32_t conf_addr; 134 conf_addr = CONF_ADDR( dev_data->bus, dev_data->dev, dev_data->fn, reg);135 void *addr = bus _data->conf_data_port + (reg & 3);136 137 pio_write_32(bus _data->conf_addr_port, conf_addr);135 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 136 void *addr = bus->conf_data_port + (reg & 3); 137 138 pio_write_32(bus->conf_addr_port, conf_addr); 138 139 139 140 switch (len) { … … 149 150 } 150 151 151 fibril_mutex_unlock(&bus_data->conf_mutex); 152 } 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; 160 161 fibril_mutex_lock(&bus_data->conf_mutex); 152 fibril_mutex_unlock(&bus->conf_mutex); 153 } 154 155 static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 156 { 157 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun); 158 159 fibril_mutex_lock(&bus->conf_mutex); 162 160 163 161 uint32_t conf_addr; 164 conf_addr = CONF_ADDR( dev_data->bus, dev_data->dev, dev_data->fn, reg);165 void *addr = bus _data->conf_data_port + (reg & 3);166 167 pio_write_32(bus _data->conf_addr_port, conf_addr);162 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 163 void *addr = bus->conf_data_port + (reg & 3); 164 165 pio_write_32(bus->conf_addr_port, conf_addr); 168 166 169 167 switch (len) { … … 179 177 } 180 178 181 fibril_mutex_unlock(&bus _data->conf_mutex);182 } 183 184 uint8_t pci_conf_read_8( device_t *dev, int reg)179 fibril_mutex_unlock(&bus->conf_mutex); 180 } 181 182 uint8_t pci_conf_read_8(pci_fun_t *fun, int reg) 185 183 { 186 184 uint8_t res; 187 pci_conf_read( dev, reg, &res, 1);185 pci_conf_read(fun, reg, &res, 1); 188 186 return res; 189 187 } 190 188 191 uint16_t pci_conf_read_16( device_t *dev, int reg)189 uint16_t pci_conf_read_16(pci_fun_t *fun, int reg) 192 190 { 193 191 uint16_t res; 194 pci_conf_read( dev, reg, (uint8_t *) &res, 2);192 pci_conf_read(fun, reg, (uint8_t *) &res, 2); 195 193 return res; 196 194 } 197 195 198 uint32_t pci_conf_read_32( device_t *dev, int reg)196 uint32_t pci_conf_read_32(pci_fun_t *fun, int reg) 199 197 { 200 198 uint32_t res; 201 pci_conf_read( dev, reg, (uint8_t *) &res, 4);199 pci_conf_read(fun, reg, (uint8_t *) &res, 4); 202 200 return res; 203 201 } 204 202 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; 223 match_id_t *match_id = NULL; 203 void pci_conf_write_8(pci_fun_t *fun, int reg, uint8_t val) 204 { 205 pci_conf_write(fun, reg, (uint8_t *) &val, 1); 206 } 207 208 void pci_conf_write_16(pci_fun_t *fun, int reg, uint16_t val) 209 { 210 pci_conf_write(fun, reg, (uint8_t *) &val, 2); 211 } 212 213 void pci_conf_write_32(pci_fun_t *fun, int reg, uint32_t val) 214 { 215 pci_conf_write(fun, reg, (uint8_t *) &val, 4); 216 } 217 218 void pci_fun_create_match_ids(pci_fun_t *fun) 219 { 224 220 char *match_id_str; 225 226 match_id = create_match_id(); 227 if (match_id != NULL) { 228 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 229 dev_data->vendor_id, dev_data->device_id); 230 match_id->id = match_id_str; 231 match_id->score = 90; 232 add_match_id(&dev->match_ids, match_id); 233 } 234 221 int rc; 222 223 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 224 fun->vendor_id, fun->device_id); 225 226 if (match_id_str == NULL) { 227 printf(NAME ": out of memory creating match ID.\n"); 228 return; 229 } 230 231 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 90); 232 if (rc != EOK) { 233 printf(NAME ": error adding match ID: %s\n", 234 str_error(rc)); 235 } 236 235 237 /* TODO add more ids (with subsys ids, using class id etc.) */ 236 238 } 237 239 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; 240 void pci_add_range(pci_fun_t *fun, uint64_t range_addr, size_t range_size, 241 bool io) 242 { 243 hw_resource_list_t *hw_res_list = &fun->hw_resources; 243 244 hw_resource_t *hw_resources = hw_res_list->resources; 244 245 size_t count = hw_res_list->count; … … 265 266 * address add it to the devices hw resource list. 266 267 * 267 * @param dev The pci device.268 * @param fun PCI function 268 269 * @param addr The address of the BAR in the PCI configuration address space of 269 * the device .270 * @return The addr the address of the BAR which should be read next .270 * the device 271 * @return The addr the address of the BAR which should be read next 271 272 */ 272 int pci_read_bar( device_t *dev, int addr)273 { 273 int pci_read_bar(pci_fun_t *fun, int addr) 274 { 274 275 /* Value of the BAR */ 275 276 uint32_t val, mask; … … 285 286 286 287 /* Get the value of the BAR. */ 287 val = pci_conf_read_32( dev, addr);288 val = pci_conf_read_32(fun, addr); 288 289 289 290 io = (bool) (val & 1); … … 305 306 306 307 /* Get the address mask. */ 307 pci_conf_write_32( dev, addr, 0xffffffff);308 mask = pci_conf_read_32( dev, addr);308 pci_conf_write_32(fun, addr, 0xffffffff); 309 mask = pci_conf_read_32(fun, addr); 309 310 310 311 /* Restore the original value. */ 311 pci_conf_write_32( dev, addr, val);312 val = pci_conf_read_32( dev, addr);312 pci_conf_write_32(fun, addr, val); 313 val = pci_conf_read_32(fun, addr); 313 314 314 315 range_size = pci_bar_mask_to_size(mask); 315 316 316 317 if (addrw64) { 317 range_addr = ((uint64_t)pci_conf_read_32( dev, addr + 4) << 32) |318 range_addr = ((uint64_t)pci_conf_read_32(fun, addr + 4) << 32) | 318 319 (val & 0xfffffff0); 319 320 } else { … … 322 323 323 324 if (range_addr != 0) { 324 printf(NAME ": device %s : ", dev->name);325 printf(NAME ": function %s : ", fun->fnode->name); 325 326 printf("address = %" PRIx64, range_addr); 326 327 printf(", size = %x\n", (unsigned int) range_size); 327 328 } 328 329 329 pci_add_range( dev, range_addr, range_size, io);330 pci_add_range(fun, range_addr, range_size, io); 330 331 331 332 if (addrw64) … … 335 336 } 336 337 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; 338 void pci_add_interrupt(pci_fun_t *fun, int irq) 339 { 340 hw_resource_list_t *hw_res_list = &fun->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->fnode->name, irq); 353 } 354 355 void pci_read_interrupt(pci_fun_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 parent The host-to-pci bridge device.365 * @param bus_num The bus number.364 * @param bus Host-to-PCI bridge 365 * @param bus_num 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(pci_bus_t *bus, int bus_num) 368 { 369 ddf_fun_t *fnode; 370 pci_fun_t *fun; 373 371 374 372 int child_bus = 0; 375 373 int dnum, fnum; 376 374 bool multi; 377 uint8_t header_type; 375 uint8_t header_type; 376 377 fun = pci_fun_new(bus); 378 378 379 379 for (dnum = 0; dnum < 32; dnum++) { 380 380 multi = true; 381 381 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,382 pci_fun_init(fun, bus_num, dnum, fnum); 383 fun->vendor_id = pci_conf_read_16(fun, 384 384 PCI_VENDOR_ID); 385 dev_data->device_id = pci_conf_read_16(dev,385 fun->device_id = pci_conf_read_16(fun, 386 386 PCI_DEVICE_ID); 387 if ( dev_data->vendor_id == 0xffff) {387 if (fun->vendor_id == 0xffff) { 388 388 /* 389 389 * The device is not present, go on scanning the … … 396 396 } 397 397 398 header_type = pci_conf_read_8( dev, PCI_HEADER_TYPE);398 header_type = pci_conf_read_8(fun, PCI_HEADER_TYPE); 399 399 if (fnum == 0) { 400 400 /* Is the device multifunction? */ … … 404 404 header_type = header_type & 0x7F; 405 405 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; 406 char *fun_name = pci_fun_create_name(fun); 407 if (fun_name == NULL) { 408 printf(NAME ": out of memory.\n"); 409 return; 410 } 411 412 fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name); 413 if (fnode == NULL) { 414 printf(NAME ": error creating function.\n"); 415 return; 416 } 417 418 free(fun_name); 419 fun->fnode = fnode; 420 421 pci_alloc_resource_list(fun); 422 pci_read_bars(fun); 423 pci_read_interrupt(fun); 424 425 fnode->ops = &pci_fun_ops; 426 fnode->driver_data = fun; 427 428 printf(NAME ": adding new function %s.\n", 429 fnode->name); 430 431 pci_fun_create_match_ids(fun); 432 433 if (ddf_fun_bind(fnode) != EOK) { 434 pci_clean_resource_list(fun); 435 clean_match_ids(&fnode->match_ids); 436 free((char *) fnode->name); 437 fnode->name = NULL; 424 438 continue; 425 439 } … … 427 441 if (header_type == PCI_HEADER_TYPE_BRIDGE || 428 442 header_type == PCI_HEADER_TYPE_CARDBUS) { 429 child_bus = pci_conf_read_8( dev,443 child_bus = pci_conf_read_8(fun, 430 444 PCI_BRIDGE_SEC_BUS_NUM); 431 445 printf(NAME ": device is pci-to-pci bridge, " 432 446 "secondary bus number = %d.\n", bus_num); 433 447 if (child_bus > bus_num) 434 pci_bus_scan( parent, child_bus);448 pci_bus_scan(bus, child_bus); 435 449 } 436 450 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; 451 fun = pci_fun_new(bus); 442 452 } 443 453 } 444 454 445 if (dev_data->vendor_id == 0xffff) { 446 delete_device(dev); 447 /* Free the auxiliary device structure. */ 448 delete_pci_dev_data(dev_data); 449 } 450 } 451 452 static int pci_add_device(device_t *dev) 453 { 455 if (fun->vendor_id == 0xffff) { 456 /* Free the auxiliary function structure. */ 457 pci_fun_delete(fun); 458 } 459 } 460 461 static int pci_add_device(ddf_dev_t *dnode) 462 { 463 pci_bus_t *bus = NULL; 464 ddf_fun_t *ctl = NULL; 465 bool got_res = false; 466 int rc; 467 454 468 printf(NAME ": pci_add_device\n"); 455 456 pci_bus_data_t *bus_data = create_pci_bus_data(); 457 if (bus_data == NULL) { 469 dnode->parent_phone = -1; 470 471 bus = pci_bus_new(); 472 if (bus == NULL) { 458 473 printf(NAME ": pci_add_device allocation failed.\n"); 459 return ENOMEM; 460 } 461 462 dev->parent_phone = devman_parent_device_connect(dev->handle, 474 rc = ENOMEM; 475 goto fail; 476 } 477 bus->dnode = dnode; 478 dnode->driver_data = bus; 479 480 dnode->parent_phone = devman_parent_device_connect(dnode->handle, 463 481 IPC_FLAG_BLOCKING); 464 if (d ev->parent_phone < 0) {482 if (dnode->parent_phone < 0) { 465 483 printf(NAME ": pci_add_device failed to connect to the " 466 484 "parent's driver.\n"); 467 delete_pci_bus_data(bus_data);468 return EPARTY; /* FIXME: use another EC */485 rc = dnode->parent_phone; 486 goto fail; 469 487 } 470 488 471 489 hw_resource_list_t hw_resources; 472 490 473 if (!get_hw_resources(dev->parent_phone, &hw_resources)) { 491 rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources); 492 if (rc != EOK) { 474 493 printf(NAME ": pci_add_device failed to get hw resources for " 475 494 "the device.\n"); 476 delete_pci_bus_data(bus_data); 477 ipc_hangup(dev->parent_phone); 478 return EPARTY; /* FIXME: use another EC */ 479 } 495 goto fail; 496 } 497 got_res = true; 480 498 481 499 printf(NAME ": conf_addr = %" PRIx64 ".\n", … … 486 504 assert(hw_resources.resources[0].res.io_range.size == 8); 487 505 488 bus _data->conf_io_addr =506 bus->conf_io_addr = 489 507 (uint32_t) hw_resources.resources[0].res.io_range.address; 490 508 491 if (pio_enable((void *)(uintptr_t)bus _data->conf_io_addr, 8,492 &bus _data->conf_addr_port)) {509 if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8, 510 &bus->conf_addr_port)) { 493 511 printf(NAME ": failed to enable configuration ports.\n"); 494 delete_pci_bus_data(bus_data); 495 ipc_hangup(dev->parent_phone); 496 clean_hw_resource_list(&hw_resources); 497 return EADDRNOTAVAIL; 498 } 499 bus_data->conf_data_port = (char *) bus_data->conf_addr_port + 4; 500 501 dev->driver_data = bus_data; 502 503 /* Enumerate child devices. */ 512 rc = EADDRNOTAVAIL; 513 goto fail; 514 } 515 bus->conf_data_port = (char *) bus->conf_addr_port + 4; 516 517 /* Make the bus device more visible. It has no use yet. */ 518 printf(NAME ": adding a 'ctl' function\n"); 519 520 ctl = ddf_fun_create(bus->dnode, fun_exposed, "ctl"); 521 if (ctl == NULL) { 522 printf(NAME ": error creating control function.\n"); 523 rc = ENOMEM; 524 goto fail; 525 } 526 527 rc = ddf_fun_bind(ctl); 528 if (rc != EOK) { 529 printf(NAME ": error binding control function.\n"); 530 goto fail; 531 } 532 533 /* Enumerate functions. */ 504 534 printf(NAME ": scanning the bus\n"); 505 pci_bus_scan( dev, 0);506 507 clean_hw_resource_list(&hw_resources);535 pci_bus_scan(bus, 0); 536 537 hw_res_clean_resource_list(&hw_resources); 508 538 509 539 return EOK; 540 541 fail: 542 if (bus != NULL) 543 pci_bus_delete(bus); 544 if (dnode->parent_phone >= 0) 545 async_hangup(dnode->parent_phone); 546 if (got_res) 547 hw_res_clean_resource_list(&hw_resources); 548 if (ctl != NULL) 549 ddf_fun_destroy(ctl); 550 551 return rc; 510 552 } 511 553 512 554 static void pciintel_init(void) 513 555 { 514 pci_child_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_child_res_iface; 515 } 516 517 pci_dev_data_t *create_pci_dev_data(void) 518 { 519 pci_dev_data_t *res = (pci_dev_data_t *) malloc(sizeof(pci_dev_data_t)); 520 521 if (res != NULL) 522 memset(res, 0, sizeof(pci_dev_data_t)); 523 return res; 524 } 525 526 void init_pci_dev_data(pci_dev_data_t *dev_data, int bus, int dev, int fn) 527 { 528 dev_data->bus = bus; 529 dev_data->dev = dev; 530 dev_data->fn = fn; 531 } 532 533 void delete_pci_dev_data(pci_dev_data_t *dev_data) 534 { 535 if (dev_data != NULL) { 536 clean_hw_resource_list(&dev_data->hw_resources); 537 free(dev_data); 538 } 539 } 540 541 void create_pci_dev_name(device_t *dev) 542 { 543 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 556 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 557 } 558 559 pci_fun_t *pci_fun_new(pci_bus_t *bus) 560 { 561 pci_fun_t *fun; 562 563 fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t)); 564 if (fun == NULL) 565 return NULL; 566 567 fun->busptr = bus; 568 return fun; 569 } 570 571 void pci_fun_init(pci_fun_t *fun, int bus, int dev, int fn) 572 { 573 fun->bus = bus; 574 fun->dev = dev; 575 fun->fn = fn; 576 } 577 578 void pci_fun_delete(pci_fun_t *fun) 579 { 580 assert(fun != NULL); 581 hw_res_clean_resource_list(&fun->hw_resources); 582 free(fun); 583 } 584 585 char *pci_fun_create_name(pci_fun_t *fun) 586 { 544 587 char *name = NULL; 545 588 546 asprintf(&name, "%02x:%02x.%01x", dev_data->bus, dev_data->dev, 547 dev_data->fn); 548 dev->name = name; 549 } 550 551 bool pci_alloc_resource_list(device_t *dev) 552 { 553 pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data; 554 555 dev_data->hw_resources.resources = 589 asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev, 590 fun->fn); 591 return name; 592 } 593 594 bool pci_alloc_resource_list(pci_fun_t *fun) 595 { 596 fun->hw_resources.resources = 556 597 (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t)); 557 return dev_data->hw_resources.resources != NULL; 558 } 559 560 void pci_clean_resource_list(device_t *dev) 561 { 562 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 563 564 if (dev_data->hw_resources.resources != NULL) { 565 free(dev_data->hw_resources.resources); 566 dev_data->hw_resources.resources = NULL; 567 } 568 } 569 570 /** Read the base address registers (BARs) of the device and adds the addresses 571 * to its hw resource list. 598 return fun->hw_resources.resources != NULL; 599 } 600 601 void pci_clean_resource_list(pci_fun_t *fun) 602 { 603 if (fun->hw_resources.resources != NULL) { 604 free(fun->hw_resources.resources); 605 fun->hw_resources.resources = NULL; 606 } 607 } 608 609 /** Read the base address registers (BARs) of the function and add the addresses 610 * to its HW resource list. 572 611 * 573 * @param dev the pci device.612 * @param fun PCI function 574 613 */ 575 void pci_read_bars( device_t *dev)614 void pci_read_bars(pci_fun_t *fun) 576 615 { 577 616 /* … … 582 621 583 622 while (addr <= PCI_BASE_ADDR_5) 584 addr = pci_read_bar( dev, addr);623 addr = pci_read_bar(fun, addr); 585 624 } 586 625 … … 594 633 printf(NAME ": HelenOS pci bus driver (intel method 1).\n"); 595 634 pciintel_init(); 596 return d river_main(&pci_driver);635 return ddf_driver_main(&pci_driver); 597 636 } 598 637
Note:
See TracChangeset
for help on using the changeset viewer.