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